/***********************************************************
 *  CcDecl.c.c
 *
 *  Created on: 2009/8/21
 *  Author: ト ,陳
 *  CopyRight: CBS tech
 *  役割り：定義文解析
 *  作り：新規
***********************************************************/
#include "../coredef.h"
#include "cc.h"
static AST	ccDeclAnlPtr( AST  astDeclaration, UCHAR ucNameSpace );
static AST	ccDeclAnlDirect(AST astDeclaration, UCHAR ucNameSpace );
static U4 ccDeclStUnSize( U2 usKind, AST astParamChain, U4 *pAlignment );

static CHAR gblTempBuffer[128]="";
static AST  ccDeclGetCodeScp( AST codeScpBegin, AST codeScpEnd ){
	codeScpEnd = stCoreCodeScpAccess.mergeCodeScp( codeScpBegin, codeScpEnd );
	if( codeScpEnd == 0 ){
		return codeScpBegin;
	}
	return codeScpEnd;
}
/*************************************************
 * return true when the current token is a delimiter
 *   of declaration.
 * otherwise return false.
 *************************************************/
static BOOL ccDeclTestDelimiter(  UCHAR ucNameSpace  ){
	AST astCurrToken ;
	U4 currTokenKind ;
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	/*  xNAMESPACE_TAG  xNAMESPACE_LABEL ここに入らない        */
	if(ucNameSpace == xNAMESPACE_ARG){
		if(currTokenKind == xLEX_COMMA || currTokenKind == xLEX_CLOSEPAREN ){
			return (TRUE);
		}
	}else if(ucNameSpace == xNAMESPACE_TYPENAME){
		if( currTokenKind == xLEX_CLOSEPAREN){
			return (TRUE);
		}
	}else if(ucNameSpace == xNAMESPACE_MEM){
		if( currTokenKind == xLEX_SEMICOLON ){
			return TRUE;
		}else if( currTokenKind == xLEX_CLOSEBLOCK ){
			return (TRUE);
		}
	}else{
		if( currTokenKind == xLEX_SEMICOLON ){
			return TRUE;
		}
	}
	return FALSE;
}
static VOID ccDeclAlertBlankDeclaration( AST astDeclaration )
{
	AST astTypeSpec = stDeclarationAccess.typeSpecifier.get( astDeclaration );
	AST astDeclarator = stDeclarationAccess.declarator.get( astDeclaration );
	AST astSym;
	BOOL bWarning = FALSE;
	PSZ  szSymName;
	AST astCodeScp = stDeclarationAccess.codeScp.get( astDeclaration );
	if( astDeclarator == 0 ){
		if( astTypeSpec != 0 ){
			switch( stTypeSpecifierAccess.specifyKind.get( astTypeSpec )){
			case TYPEDEF_BASE:
				bWarning = TRUE;
				break;
			case TYPEDEF_ENUM:
				astSym = stTypeSpecifierAccess.symbol.get( astTypeSpec );
				szSymName = stSymbolInfoAccess.name.get( astSym );
				if( str_length( szSymName ) > 0  ){
					break;
				}
				if( stTypeSpecifierAccess.memberChain.get( astTypeSpec ) > 0 ){
					break;
				}
				bWarning = TRUE;
				break;
			case TYPEDEF_STRUCT:
			case TYPEDEF_UNION:
				astSym = stTypeSpecifierAccess.symbol.get( astTypeSpec );
				szSymName = stSymbolInfoAccess.name.get( astSym );
				if( str_length( szSymName ) > 0  ){
					break;
				}
				bWarning = TRUE;
				break;
			case TYPEDEF_TYPEDEF:
				bWarning = TRUE;
				break;
			}
		}
	}
	if( bWarning ){
		CcThrowWarning( CC_DECL_DECLARE_NOTHING, astCodeScp, NULL, NULL );
	}
}
static VOID ccDeclSkipAttribute( VOID ){
	U4 currTokenKind;
	AST astCurrToken;
	astCurrToken = CcLexGetCurrToken() ;
    currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
    if( currTokenKind == xLEX_ATTRIBUTE ){
    	astCurrToken = CcLexGetNextToken() ;
        currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
        if( currTokenKind == xLEX_OPENPAREN ){
        	do{
        		astCurrToken = CcLexGetNextToken() ;
        		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
        	}while( currTokenKind != xLEX_CLOSEPAREN
        			&&	currTokenKind != xLEX_SEMICOLON
        			&&	currTokenKind != xLEX_ENDOFFILE );
        	if( currTokenKind == xLEX_CLOSEPAREN ){
        		astCurrToken = CcLexGetNextToken() ;
        	}
        }
    }
}
static BOOL ccDeclIsParenDeclarator( UCHAR ucNameSpace ){
	AST  astMark = CcLexGetCurrToken();
	BOOL bNestCall = TRUE;
	U4 currTokenKind;
	AST astCurrToken;

	astCurrToken = CcLexGetNextToken() ;
    currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
    if( currTokenKind == xLEX_MUL ){
    	/* "*"  : ( declarator )  */
    	bNestCall = TRUE;
    }else if( currTokenKind == xLEX_SYMBOL ){
    	if( ucNameSpace == xNAMESPACE_TYPENAME ){
    		/* treat as parameter. variable name should not exist. */
    		bNestCall = FALSE;
    	}else if( ucNameSpace == xNAMESPACE_MEM || ucNameSpace == xNAMESPACE_ORD ){
    		/* It needs symbol */
    		bNestCall = TRUE;
    	}else if( CcDeclChkType( astCurrToken ) ){
    		/* xNAMESPACE_ARG  typedef symbol : function argument-list */
    		bNestCall = FALSE;
    	}else {
    		/* xNAMESPACE_ARG  general symbol , parameter name  */
    		bNestCall = TRUE;
    	}
    }else {
    	bNestCall = FALSE;
    }
    CcLexBackto( astMark );
    return bNestCall;
}

/***********************************************************
 * 1. 関数名		ccDeclAnlArray
 * 2. 引数	    　　pastDeclarator
 * 3. 戻り値		COEXIT_SUCCESS		正常終了
 *   			COEXIT_FATAL		致命エラー
***********************************************************/
static AST ccDeclAnlArray(  AST astDeclaration, AST  astFuncSymDel, UCHAR ucNameSpace )
{
	S4 	astArrDec =0;										/*配列宣言子		*/
	U4	u4EndChar[2]={xLEX_CLOSEARRAY,xLEX_UNDEFINED};	/*終了文字配列		*/
	S4	astExprConst ;									/*要素数の定数式	*/

	AST  astCurrToken;
	U4  currTokenKind;
	AST  firstScp, secondScp;

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

	if( astFuncSymDel == 0 ){
		firstScp = stLexTokenAccess.codeScp.get( astCurrToken );
	}else{
		firstScp = stDeclaratorAccess.codeScp.get( astFuncSymDel );
	}
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

	TRY;

	stDeclaratorAccess.alloc(1);
	astArrDec = stDeclaratorAccess.getMax();

	stDeclaratorAccess.declaration.set( astArrDec, astDeclaration );
	stDeclaratorAccess.declaratorKind.set(astArrDec, xDECLARATOR_ARRAY);

	if ( currTokenKind != xLEX_CLOSEARRAY){
		astExprConst = CcConstantExpression( u4EndChar, KIND_DECLARATOR, astArrDec );
		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if ( currTokenKind != xLEX_CLOSEARRAY ){
			CcThrowWarning( CC_DECL_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
			while(   currTokenKind != xLEX_CLOSEARRAY
			       && currTokenKind != xLEX_SEMICOLON
			       && currTokenKind != xLEX_EQU
			       && currTokenKind != xLEX_OPENBLOCK
			       && currTokenKind != xLEX_CLOSEBLOCK
			       && currTokenKind != xLEX_ENDOFFILE ){
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			}
		}
		stDeclaratorAccess.arrayIdx.set(astArrDec, astExprConst );
	}
	if( currTokenKind == xLEX_CLOSEARRAY ){
		astCurrToken = CcLexGetNextToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	}
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1));
	secondScp = ccDeclGetCodeScp( firstScp, secondScp );
	stDeclaratorAccess.codeScp.set( astArrDec, secondScp );
	CATCH(astArrDec);
	return( astArrDec );
}
static VOID ccDeclSetFuncSymbolType( AST astNewDeclarator, AST astFuncDeclarator ){
	AST astDeclaration = stDeclaratorAccess.paramChain.get(astFuncDeclarator);
	AST astNewsym = CcDeclGetSymfromDec( astNewDeclarator );
	AST astOldSym=0;
	PSZ name1,name2;
	AST astDeclarator;


	name2 = stSymbolInfoAccess.name.get( astNewsym );
	if( name2 == NULL ){
		CcThrowWarning( CC_DECL_FUNC_OLDSTYLE_DECLIST_WRONGNAME,
				stDeclaratorAccess.codeScp.get( astNewDeclarator ),
				"", NULL );
		return ;
	}

	while( astDeclaration ){
		astDeclarator = stDeclarationAccess.declarator.get( astDeclaration );
		while(astDeclarator){
			astOldSym = CcDeclGetSymfromDec( astDeclarator );
			name1 = stSymbolInfoAccess.name.get( astOldSym );
			if( 0 == strcmp ( name1, name2 ) ){
				break;
			}
			astDeclarator = stDeclaratorAccess.nextDeclarator.get(astDeclarator );
		}
		if( astDeclarator ){
			break;
		}
		astDeclaration = stDeclarationAccess.next.get( astDeclaration );
	}
	if( astOldSym == 0 ){
		CcThrowWarning( CC_DECL_FUNC_OLDSTYLE_DECLIST_WRONGNAME,
				stDeclaratorAccess.codeScp.get( astNewDeclarator ),
				name2, NULL );
		return ;
	}
	stSymbolInfoAccess.codeScp.set( astOldSym, stDeclaratorAccess.codeScp.get( astNewDeclarator ));
	stSymbolInfoAccess.type.set( astOldSym, stSymbolInfoAccess.type.get( astNewsym ));
}
static VOID ccDeclAnlFuncParamList(AST astFuncDeclarator, AST  astFuncSymDel ){
	AST astCurrToken;
	AST astDeclaration;
	AST astDeclarator;
	U4 currTokenKind;

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	while( CcDeclChkType(astCurrToken) ){
		astDeclaration = CcDeclaration( xNAMESPACE_ORD );
		astDeclarator = stDeclarationAccess.declarator.get( astDeclaration );
		while(astDeclarator){
			ccDeclSetFuncSymbolType( astDeclarator, astFuncDeclarator );
			astDeclarator = stDeclaratorAccess.nextDeclarator.get(astDeclarator );
		}
		astCurrToken = CcLexGetCurrToken();
	}
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind != xLEX_OPENBLOCK ){
		CcThrowWarning( CC_DECL_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
		while(TRUE)	{
		    if(    currTokenKind == xLEX_SEMICOLON
		        || currTokenKind == xLEX_OPENBLOCK
		        || currTokenKind == xLEX_CLOSEBLOCK
		        || currTokenKind == xLEX_ENDOFFILE ){
		        break ;
		    }
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}
		if( currTokenKind == xLEX_SEMICOLON ){
			astCurrToken = CcLexGetNextToken();
		}
	}
}
static AST	ccDeclAnlFunc(  AST astDeclaration, AST  astFuncSymDel, UCHAR ucNameSpace )
{
	AST	astFunDec =0; 			/*関数宣言子			*/
	AST	astParmKind ;			/*引数種別			*/
	AST	astPreParmChain ;		/*直前の引数チェーン		*/
	S4	astNowParmInfo ;		/*現在の引数情報		*/
//	S4	astRngMan ;				/*有効範囲管理情報		*/
	AST		astNowDecl;
	BOOL	RetBool ;
	AST     astCurrToken;
	U4     currTokenKind;
	AST    astSym;
	AST     firstScp, secondScp;

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( astFuncSymDel == 0 ){
		firstScp = stLexTokenAccess.codeScp.get( astCurrToken );
	}else{
		firstScp = stDeclaratorAccess.codeScp.get( astFuncSymDel );
	}
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	TRY;

	stDeclaratorAccess.alloc(1);
	astFunDec = stDeclaratorAccess.getMax();

	stDeclaratorAccess.declaration.set( astFunDec, astDeclaration );
	stDeclaratorAccess.declaratorKind.set(astFunDec, xDECLARATOR_FUNC);
	CATCH(astFunDec);
	astParmKind = xPARAM_NOTHING;
	astPreParmChain = 0;

	/*debug,12/10/03,S*/
	if(currTokenKind == xLEX_CLOSEPAREN){
		astCurrToken = CcLexGetNextToken();
		return astFunDec;
	}
	/*debug,12/10/03,E*/

	while (currTokenKind != xLEX_CLOSEPAREN && currTokenKind != xLEX_ENDOFFILE ){
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if (currTokenKind == xLEX_ELLIPSIS ){
			CcThrowWarning( CC_DECL_FUNC_PARAM_CHANGEABLE,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					NULL, NULL );
			if (astPreParmChain == 0){
				CcThrowWarning( CC_DECL_FUNC_PARAM_FORMAT_ILLEGAL,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}
			TRY;

			/* 可変引数に対応　仮　*/
			stDeclarationAccess.alloc(1);
			astNowParmInfo = stDeclarationAccess.getMax();

			stDeclarationAccess.codeScp.set( astNowParmInfo, stLexTokenAccess.codeScp.get( astCurrToken ));
			if (astPreParmChain == 0){
				stDeclaratorAccess.paramChain.set(astFunDec, astNowParmInfo);
			}
			else{
				stDeclarationAccess.next.set(astPreParmChain, astNowParmInfo);
			}
			astPreParmChain = astNowParmInfo;
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			/* 可変引数に対応　仮　*/
			if (currTokenKind == xLEX_CLOSEPAREN){
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
				break;
			}else{
				CcThrowWarning( CC_DECL_FUNC_PARAM_FORMAT_ILLEGAL,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
				while (currTokenKind != xLEX_CLOSEPAREN
						&& currTokenKind != xLEX_OPENBLOCK
						&& currTokenKind != xLEX_SEMICOLON
						&& currTokenKind != xLEX_ENDOFFILE ){
					astCurrToken = CcLexGetNextToken();
					currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
				}
				if (currTokenKind == xLEX_CLOSEPAREN){
					astCurrToken = CcLexGetNextToken();
					currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
					break;
				}else{
					break;
				}
			}
			CATCH(astFunDec);
		}
		astNowDecl = 0;
		RetBool = CcDeclChkType(astCurrToken);
		if (RetBool == FALSE ){
			if( currTokenKind == xLEX_SYMBOL ){
				astCurrToken = CcLexGetRT(1);
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
				if( xLEX_COMMA == currTokenKind || currTokenKind == xLEX_CLOSEPAREN ){
					stDeclarationAccess.alloc(1);
					astNowDecl = stDeclarationAccess.getMax();
					astCurrToken = CcLexGetCurrToken();
					astSym = CcSymNewParameter( stLexTokenAccess.name.get( astCurrToken )  );
					stSymbolInfoAccess.codeScp.set( astSym,stLexTokenAccess.codeScp.get( astCurrToken ));
					stSymbolInfoAccess.type.set( astSym, 0 );
					stDeclarationAccess.codeScp.set( astNowDecl, stLexTokenAccess.codeScp.get( astCurrToken ) );
				}
			}
		}
		if (astNowDecl != 0){
			if (astParmKind == xPARAM_NOTHING ){
				astParmKind = xPARAM_SYMBOLLIST;
			}else if( astParmKind == xPARAM_PARAMETERLIST ){
				CcThrowWarning( CC_DECL_FUNC_PARAM_NOTYPE,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
				astNowDecl = 0;
			}
		}
		if( astNowDecl == 0 ){
			TRY;
			astNowDecl = CcDeclaration( xNAMESPACE_ARG );
			CATCH(astFunDec);
		}
		if( astNowDecl >= MIN_ARRAY ){
			astNowParmInfo = astNowDecl;
			if (astPreParmChain == 0){
				stDeclaratorAccess.paramChain.set(astFunDec, astNowParmInfo);
			}
			else{
				stDeclarationAccess.next.set(astPreParmChain, astNowParmInfo);
			}
			astPreParmChain = astNowParmInfo;
			stDeclarationAccess.parentKind.set(astNowParmInfo, KIND_DECLARATOR );
			stDeclarationAccess.parentIdx.set(astNowParmInfo, astFunDec );
		}
		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if (currTokenKind ==  xLEX_COMMA){
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}else if (currTokenKind == xLEX_CLOSEPAREN){
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}else{
			CcThrowWarning( CC_DECL_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
			while (currTokenKind != xLEX_CLOSEPAREN
					&& currTokenKind != xLEX_COMMA
					&& currTokenKind != xLEX_SEMICOLON
					&& currTokenKind != xLEX_OPENBLOCK
					&& currTokenKind != xLEX_ENDOFFILE){
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			}
			if (currTokenKind == xLEX_COMMA ){
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
				continue ;
			}else if (currTokenKind == xLEX_CLOSEPAREN){
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
				break ;
			}else{
				break ;
			}
		}
	}
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1));
	secondScp = ccDeclGetCodeScp( firstScp, secondScp );
	stDeclaratorAccess.codeScp.set( astFunDec, secondScp );
	TRY;
	if (astParmKind == xPARAM_SYMBOLLIST){
//		astRngMan = stBlockNestAccess.getMax();
		if ( ucNameSpace == xNAMESPACE_ORD ){
			if( CcDeclChkType( astCurrToken ) == TRUE ){
				ccDeclAnlFuncParamList(astFunDec, astFuncSymDel );
			}
		}else{
			CcThrowWarning( CC_DECL_FUNC_OLDSTYLE_MISUSE,
					secondScp,
					NULL, NULL );
		}
	}

	CATCH(astFunDec);
	return (astFunDec);
}

/************************************************************
 * 1. 関数名	  ccDeclAnlDirect
 * 2. 引数	  astDeclaration
 *	          pastDeclaration	    　　宣言子のリターン値ポイント
 *	          ucNameSpace	                解析種類
 * 3. 戻り値	  EXIT_SUCCESS		        正常終了
 *            EXIT_FATAL		        致命エラー
 * 4．詳細：	  <1> ポインタ宣言子として、解析する
 *            <2> 初期化コードを解析.
************************************************************/
static AST	ccDeclAnlDirect(AST astDeclaration, UCHAR ucNameSpace )
{
	AST     astDirectDeclInfo ;
	AST     astPtrDeclInfo ;
	AST     astAfterDeclInfo ;
	AST     astSuffixDeclInfo ;
	U4      currTokenKind;
	BOOL    bNestCall = FALSE;
	AST     firstScp, secondScp;
	AST     astResult = 0;
	AST     astCurrToken = CcLexGetCurrToken();

	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	astDirectDeclInfo = 0;
	if( currTokenKind == xLEX_OPENPAREN ){
		bNestCall = ccDeclIsParenDeclarator( ucNameSpace );
		if( bNestCall ){
			TRY;
			astCurrToken = CcLexGetNextToken();
			firstScp = stLexTokenAccess.codeScp.get( astCurrToken );
			astPtrDeclInfo = ccDeclAnlPtr( astDeclaration, ucNameSpace ) ;

			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		    if( currTokenKind != xLEX_CLOSEPAREN ){
				CcThrowWarning( CC_DECL_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
		    }else{
		    	astCurrToken = CcLexGetNextToken() ;
		    }
		    secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
		    secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	    	stDeclaratorAccess.alloc(1);

			astDirectDeclInfo = stDeclaratorAccess.getMax();
			stDeclaratorAccess.declaratorKind.set(astDirectDeclInfo, xDECLARATOR_PAREN);
			stDeclaratorAccess.codeScp.set(astDirectDeclInfo, secondScp);
			stDeclaratorAccess.declaration.set( astDirectDeclInfo, astDeclaration );
			if( astPtrDeclInfo != 0 ){
				stDeclaratorAccess.childDeclarator.set( astDirectDeclInfo, astPtrDeclInfo );
				stDeclaratorAccess.parentDeclarator.set( astPtrDeclInfo, astDirectDeclInfo );
			}
			CATCH(0);
		}
	}else if( currTokenKind == xLEX_SYMBOL ){
		TRY;
    	stDeclaratorAccess.alloc(1);
		astDirectDeclInfo = stDeclaratorAccess.getMax();
		stDeclaratorAccess.declaratorKind.set(astDirectDeclInfo, xDECLARATOR_SYM);
		astCurrToken = CcLexGetCurrToken();
		firstScp = stLexTokenAccess.codeScp.get( astCurrToken );
		stDeclaratorAccess.codeScp.set(astDirectDeclInfo, firstScp);
		stDeclaratorAccess.declaration.set( astDirectDeclInfo, astDeclaration );
		stDeclaratorAccess.symbol.set(astDirectDeclInfo, astCurrToken);
		astCurrToken = CcLexGetNextToken() ;
		CATCH(0);
	}
	astAfterDeclInfo = 0 ;
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	while( currTokenKind == xLEX_OPENARRAY || currTokenKind == xLEX_OPENPAREN ){
		TRY;
		if( currTokenKind == xLEX_OPENARRAY ){
			astSuffixDeclInfo = ccDeclAnlArray( astDeclaration, astDirectDeclInfo,ucNameSpace ) ;
		}else{
			astSuffixDeclInfo = ccDeclAnlFunc( astDeclaration, astDirectDeclInfo,ucNameSpace ) ;
		}
		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if( astAfterDeclInfo == 0 ){
			if( astDirectDeclInfo >= MIN_ARRAY ){
				stDeclaratorAccess.childDeclarator.set( astSuffixDeclInfo, astDirectDeclInfo );
				stDeclaratorAccess.parentDeclarator.set( astDirectDeclInfo, astSuffixDeclInfo );
			}
		}else{
			stDeclaratorAccess.childDeclarator.set( astSuffixDeclInfo, astAfterDeclInfo );
			stDeclaratorAccess.parentDeclarator.set( astAfterDeclInfo, astSuffixDeclInfo );
		}
		astAfterDeclInfo = astSuffixDeclInfo ;
		CATCH(0);
	}
    if( astAfterDeclInfo == 0 ){
    	astResult =  astDirectDeclInfo ;
    }else{
    	astResult =  astAfterDeclInfo ;
    }
    return( astResult ) ;
}

static AST	ccDeclAnlPtr( AST  astDeclaration, UCHAR ucNameSpace ){
	AST astCurPtrDel ;
	AST astDirectDeclInfo ;
	AST astCurrToken;
	U4  currTokenKind;
	U2 usQualNum=0 ;
	AST firstCodeScp=0, secondCodeScp=0;
	AST astResult=0;

	astCurPtrDel = 0 ;
	astCurrToken = CcLexGetCurrToken();
    currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

    if( currTokenKind == xLEX_MUL ){
    	TRY;
    	firstCodeScp = stLexTokenAccess.codeScp.get( astCurrToken );
    	stDeclaratorAccess.alloc(1);
		astCurPtrDel = stDeclaratorAccess.getMax();
       	astResult = astCurPtrDel ;
        stDeclaratorAccess.declaration.set(astCurPtrDel, astDeclaration);
        stDeclaratorAccess.declaratorKind.set(astCurPtrDel, xDECLARATOR_POINTER);
    	astCurrToken = CcLexGetNextToken();
        currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
        while (currTokenKind == xLEX_CONST || currTokenKind == xLEX_VOLATILE
				|| currTokenKind == xLEX_RESTRICT) {
			if (currTokenKind == xLEX_CONST) {
				/* "const" cannot come with no "*", because it's solved as type-specifier */
				usQualNum = stDeclaratorAccess.constNum.get(astCurPtrDel);
				usQualNum++;
				stDeclaratorAccess.constNum.set(astCurPtrDel, usQualNum);
			} else if (currTokenKind == xLEX_VOLATILE) {
				/* "volatile" cannot come with no "*", because it's solved as type-specifier */
				usQualNum = stDeclaratorAccess.volatileNum.get(astCurPtrDel);
				usQualNum++;
				stDeclaratorAccess.volatileNum.set(astCurPtrDel, usQualNum);
			} else {
				/* "restrict" cannot come with no "*", because it's solved as type-specifier */
				usQualNum = stDeclaratorAccess.restrictNum.get(astCurPtrDel);
				usQualNum++;
				stDeclaratorAccess.restrictNum.set(astCurPtrDel, usQualNum);
			}
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get(astCurrToken);
		}
        astDirectDeclInfo = ccDeclAnlPtr( astDeclaration, ucNameSpace) ;
        if ( astDirectDeclInfo != 0 ){
			stDeclaratorAccess.childDeclarator.set(astCurPtrDel, astDirectDeclInfo);
			stDeclaratorAccess.parentDeclarator.set(astDirectDeclInfo, astCurPtrDel);
		}
        secondCodeScp = stLexTokenAccess.codeScp.get( CcLexGetLF( 1 ) );
        stDeclaratorAccess.codeScp.set( astCurPtrDel, ccDeclGetCodeScp( firstCodeScp, secondCodeScp ));
        CATCH(0);
    }else{
    	ccDeclSkipAttribute();
    	astResult = ccDeclAnlDirect( astDeclaration, ucNameSpace) ;
    }
	return( astResult ) ;
}
static AST ccDeclSetBitField( AST astDeclaration, AST astDeclarator ){
	AST astConstExpr ;
	U4 ulEndSym[4] ;
	AST astBitField ;
	AST astCurrToken;
	U4  currTokenKind;
	AST firstCodeScp=0, secondCodeScp=0;

	firstCodeScp = stDeclaratorAccess.codeScp.get( astDeclarator );
	if (firstCodeScp == 0 ){
		firstCodeScp = stLexTokenAccess.codeScp.get( CcLexGetCurrToken() );
	}
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	ulEndSym[0] = xLEX_SEMICOLON ;
	ulEndSym[1] = xLEX_CLOSEBLOCK ;
	ulEndSym[2] = xLEX_COMMA ;
	ulEndSym[3] = xLEX_UNDEFINED ;
	astConstExpr = CcConstantExpression( ulEndSym, KIND_DECLARATOR, astDeclarator );

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

	if( astConstExpr >  0 && FALSE == stExpressionAccess.bIllegal.get( astConstExpr )){
		if( CONSTANT_VALUE != stExpressionAccess.constFlg.get( astConstExpr )){
    		CcThrowWarning( CC_DECL_MEMBER_BIT_NEED_CONSTANT,
    				stExpressionAccess.codeScp.get( astConstExpr ),
    				NULL, NULL  );
		}
	}else if( astConstExpr == 0 ||
			( currTokenKind != xLEX_SEMICOLON
					&& currTokenKind != xLEX_CLOSEBLOCK
					&& currTokenKind != xLEX_COMMA )){
		CcThrowWarning( CC_DECL_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL  );
	}

	stDeclaratorAccess.alloc(1);
	astBitField = stDeclaratorAccess.getMax();
	stDeclaratorAccess.declaratorKind.set( astBitField, DECLARATOR_BITFIELD );
	stDeclaratorAccess.bitIdx.set( astBitField, astConstExpr );
	stDeclaratorAccess.childDeclarator.set( astBitField, astDeclarator );

	stDeclaratorAccess.declaration.set( astBitField, astDeclaration );
	stDeclaratorAccess.parentDeclarator.set( astDeclarator, astBitField );

	secondCodeScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1));
	secondCodeScp = stCoreCodeScpAccess.mergeCodeScp( firstCodeScp, secondCodeScp );
	stDeclaratorAccess.codeScp.set( astBitField, secondCodeScp );
	return astBitField;
}
static AST ccDeclCreateNoNameBitField( AST astDeclaration ){
//	AST astBitDeclarator;
	AST astSymDeclarator;
	AST astCurrToken;

	stDeclaratorAccess.alloc(1);
	astSymDeclarator = stDeclaratorAccess.getMax();
	stDeclaratorAccess.declaratorKind.set(astSymDeclarator, xDECLARATOR_SYM);
	astCurrToken = CcLexGetCurrToken();
	stDeclaratorAccess.codeScp.set(astSymDeclarator, stLexTokenAccess.codeScp.get( astCurrToken ));
	stDeclaratorAccess.declaration.set( astSymDeclarator, astDeclaration );
	stDeclaratorAccess.symbol.set(astSymDeclarator, 0);

	/*astBitDeclarator = */ccDeclSetBitField( astDeclaration,  astSymDeclarator ) ;

	return( COEXIT_SUCCESS ) ;
}
static AST ccDeclInitExprList( AST astDeclaration ) {
	return CcInitializerMain();
}
static VOID ccDeclCheckInitAndType( AST astBaseTypeInfo, AST astInitExprInfo, BOOL bStatic ){
	if( stExpressionListAccess.bIllegal.get( astInitExprInfo ) ){
		return;
	}
	if( bStatic ){
		CcInitializerWarningNotConstant( astInitExprInfo );
	}
	CcInitializerCheck( astBaseTypeInfo, astInitExprInfo );
}
/************************************************************
 * 1. 関数名	  ccDeclDeclare
 * 2. 引数	  astDeclaration
 *	          pastDeclaration	    　　宣言子のリターン値ポイント
 *	          ucNameSpace
 * 3. 戻り値	  EXIT_SUCCESS		        正常終了
 *            EXIT_FATAL		        致命エラー
 * 4．詳細：	  <1> ポインタと修飾子を解析
 *            <2> 直接宣言子を解析
************************************************************/
static AST ccDeclDeclarator( AST astDeclaration, UCHAR ucNameSpace )
{
	AST  astInitDecInfo=0 ;		/* 初期化宣言子 		*/
	AST  astInitExprInfo=0 ;		/* 初期化式情報		*/
	AST  astBitFiled=0 ; /* 型指定子並び		*/
	U4  currTokenKind;
	AST astCurrToken;
	AST  firstCodeScp, secondCodeScp;
	AST  astResult=0;

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( ucNameSpace == xNAMESPACE_MEM ){
		if( currTokenKind == xLEX_COLON ){
			return ccDeclCreateNoNameBitField( astDeclaration ) ;
		}
	}
	TRY;
	astResult = ccDeclAnlPtr( astDeclaration, ucNameSpace ) ;
    firstCodeScp = stDeclaratorAccess.codeScp.get(astResult);
    astCurrToken = CcLexGetCurrToken();
    currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
    if( currTokenKind == xLEX_EQU ) {
        astCurrToken = CcLexGetNextToken();
        currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
    	astInitExprInfo = ccDeclInitExprList( astDeclaration ) ;
		if( ucNameSpace == xNAMESPACE_ORD){
			stDeclaratorAccess.alloc(1);
			astInitDecInfo = stDeclaratorAccess.getMax();
			stDeclaratorAccess.declaratorKind.set(astInitDecInfo, xDECLARATOR_INIT);
			if( astResult != 0 ){
				stDeclaratorAccess.childDeclarator.set(astInitDecInfo, astResult);
				stDeclaratorAccess.parentDeclarator.set(astResult, astInitDecInfo);
			}
			stDeclaratorAccess.declaration.set(astInitDecInfo, astDeclaration);
			stDeclaratorAccess.initialExpList.set( astInitDecInfo, astInitExprInfo );
			stExpressionListAccess.parentKind.set( astInitExprInfo, KIND_DECLARATOR );
			stExpressionListAccess.parent.set( astInitExprInfo, astInitDecInfo );
			astResult = astInitDecInfo ;

		}else if( ucNameSpace == xNAMESPACE_MEM ){
			CcThrowWarning( CC_DECL_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
        }

    }else if( currTokenKind == xLEX_COLON ) {
    	if( ucNameSpace == xNAMESPACE_ORD){
			CcThrowWarning( CC_DECL_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
    	}
    	astBitFiled = ccDeclSetBitField( astDeclaration, astResult ) ;
		if( ucNameSpace == xNAMESPACE_ORD){
			if( astResult != 0 ){
				stDeclaratorAccess.parentDeclarator.set(astResult, 0);
			}
		}else if( ucNameSpace == xNAMESPACE_MEM ){
			astResult = astBitFiled ;
		}
    }
    secondCodeScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
    stDeclaratorAccess.codeScp.set( astResult, ccDeclGetCodeScp(firstCodeScp,secondCodeScp) );
    CATCH(0);
    return( astResult ) ;
}
static AST ccDeclStructField( VOID ){
//	S4		nRet ;					/* 戻り値					*/
	AST	astNumDecl ;			/* メンバー定義				*/
	AST	astPreMemDeclChain ;	/* 直前のメンバー定義チェーン	*/
	AST  astResult=0;
	AST  astCurrToken;
	U4   currTokenKind;

	TRY;
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

	astPreMemDeclChain = 0 ;
//	nRet = COEXIT_SUCCESS;
	while (currTokenKind!=xLEX_CLOSEBLOCK && currTokenKind!=xLEX_ENDOFFILE ){
		if( currTokenKind == xLEX_CLOSEBLOCK ){
			/* } メンバーの宣言が終わる */
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break ;
		}
		/* メンバーの宣言を解析 */
		astNumDecl = CcDeclaration( xNAMESPACE_MEM );
		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if( astNumDecl < MIN_ARRAY ){
			continue;
		}
		if ( astPreMemDeclChain == 0 ){
			astResult = astNumDecl;
		}else{
			astPreMemDeclChain = stDeclarationAccess.next.set(astPreMemDeclChain, astNumDecl);
		}
		astPreMemDeclChain = astNumDecl ;
	}
	if( currTokenKind == xLEX_CLOSEBLOCK ){
		astCurrToken = CcLexGetNextToken();
	}
	CATCH( astResult );
	return (astResult);
}
static AST ccDeclResolveMemChain( AST astDeclaration ){
	BOOL bMemName;
	AST astNumDecl;
	AST astDeclor;
	AST astSymInfo;
	PSZ strRet;
	AST astType;
	AST astChain=0;
	AST astPreChain=0;
	AST astHeaderChain = 0;

	if( astDeclaration == 0 ){
		return 0;
	}
	TRY;
	bMemName = FALSE;
	/* メンバーの宣言からシンボル情報を抽出し，KIND_DEFCHAINでKIND_TYPEDEFINFOに繋ぐ */
	astNumDecl = astDeclaration;
	while( astNumDecl ){
//		bOver = FALSE;
		astDeclor = stDeclarationAccess.declarator.get( astNumDecl );
		while (astDeclor != 0){
			/* 変数情報を取得 */
			astSymInfo = CcDeclGetSymfromDec (astDeclor);
			strRet = stSymbolInfoAccess.name.get( astSymInfo );
			if ( str_length(strRet) == 0  ){
				if( astNumDecl == astDeclaration ){
					/* 一番目のメンバーは変数名がない  */
					CcThrowWarning( CC_DECL_MEMBER_1ST_NONAME,
							stDeclarationAccess.codeScp.get( astNumDecl ),
							NULL, NULL );
				}
			}else{
				/* メンバー名がある */
				bMemName =TRUE ;
			}
			astType = stSymbolInfoAccess.type.get( astSymInfo );

			if( !CcTypeIsBitfield(astType) && 0 == stTypeInfoAccess.size.get( astType ) )	{
				/* メンバーのサイズがわからない */
				if( stCoreEnvInfo.ucC90 ){
					CcThrowWarning( CC_DECL_MEMBER_NOSIZE,
							stDeclarationAccess.codeScp.get( astNumDecl ),
							strRet, NULL );
				}else{
					if( ( 0 == stDeclaratorAccess.nextDeclarator.get(astDeclor) )
						&& stDeclarationAccess.next.get( astNumDecl ) == 0
						&& stTypeInfoAccess.bSizeUnDefined.get( astType ) == FALSE ){
						;
					}else{
						CcThrowWarning( CC_DECL_MEMBER_NOSIZE,
								stDeclarationAccess.codeScp.get( astNumDecl ),
								strRet, NULL );
					}
				}
			}

			stUniteChainAccess.alloc(1);
			astChain = stUniteChainAccess.getMax();
			stUniteChainAccess.parameter_sym.set( astChain, astSymInfo );
			if( astPreChain == 0 ){
				astHeaderChain = astChain;
			}else{
				stUniteChainAccess.next.set( astPreChain, astChain );
				stUniteChainAccess.before.set( astChain, astPreChain );
			}
			astPreChain = astChain;
			astDeclor = stDeclaratorAccess.nextDeclarator.get(astDeclor);
		}
		astNumDecl = stDeclarationAccess.next.get( astNumDecl );
	}
	if( bMemName == FALSE ){
		CcThrowWarning( CC_DECL_STRUCT_NONAMED_MEMBER,
				stDeclarationAccess.codeScp.get( astDeclaration ),
				NULL, NULL );
	}
	CATCH( astHeaderChain );
	return (astHeaderChain);
}
static U4 ccDeclStUnTypeSize( U2 usKind, AST astType, U4 *pAlignment ){
	U4 u4StuckSize;
	AST astParam;

	u4StuckSize = stTypeInfoAccess.size.get( astType );
	if ( pAlignment == NULL ){
		return (u4StuckSize)	;
	}
	astParam = stTypeInfoAccess.memChain.get( astType );
	return ccDeclStUnSize( usKind, astParam, pAlignment );
}
static U4 ccDeclGetVarSize( AST astType, U4 *pAlignment ){
	U4 ulTypeKind ;
	AST astElementType ;
	U4 ulElementSize ;
	U4 ulSize ;


	ulTypeKind = stTypeInfoAccess.typeKind.get( astType ) ;
	switch( ulTypeKind )
	{
	case TYPEKIND_BASIC:
	case TYPEKIND_POINTER :
	case TYPEKIND_ENUM :
		ulSize = stTypeInfoAccess.size.get( astType );
		if(pAlignment != NULL){
		    *pAlignment = ulSize ;
		}
		break ;
	case TYPEKIND_ARRAY :
		ulSize = stTypeInfoAccess.size.get( astType );
		astElementType = stTypeInfoAccess.elementType.get( astType );
		ulElementSize = ccDeclGetVarSize( astElementType, pAlignment) ;
		ulSize = ulSize * ulElementSize ;
		break ;
	case TYPEKIND_STRUCT :
		ulSize = ccDeclStUnTypeSize( TYPEDEF_STRUCT, astType, pAlignment) ;
		break ;
	case TYPEKIND_UNION :
		ulSize = ccDeclStUnTypeSize( TYPEDEF_UNION, astType, pAlignment) ;
		break ;
	default:
		ulSize = 0 ;
		if(pAlignment){
		    *pAlignment = ulSize ;
		}
		break;
	}
	if(pAlignment){
		if( stCoreEnvInfo.ucMaxAlignment && (*pAlignment) > stCoreEnvInfo.ucMaxAlignment ){
			(*pAlignment) = stCoreEnvInfo.ucMaxAlignment;
		}
	}
    return ulSize ;
}
static U4 ccDeclStUnSize( U2 usKind, AST astParamChain, U4 *pAlignment ){
	S4	s4StuckBorderAdjust ;	/*構造体境界調整数*/
	S4	s4NumBorderAdjust ;	/*メンバー境界調整数*/
	S4	s4NumSize ;			/*メンバーサイズ*/
	S4	s4MaxNumSize ;			/*最大メンバーサイズ*/
	S4	s4JustbeforeOffset ;	/*直前のオフセット*/
	S4	s4StuckSize ;			/*構造体サイズ*/
	S4	s4UsedBit ;			/*使ったビット数*/
	S4	astBitFlag ;			/*ビットフラグ*/
	AST	astSymDefInfo ;			/*シンボル情報*/
	AST	astTypeInfo ;			/*型情報*/
	U4	ucKind ;				/*型種類*/
	S4	s4DistributionSize; 	/*分配サイズ数*/
	S4	s4BeforeNumBorderAdjust;
	S4  s4_OffsetByte = 0;
	S4  s4_OffsetBit = 0;
//	S4  s4_PreSize = 0;
//	S4  s4_CurrSize = 0;

	if ( astParamChain == 0 ){
		/* メンバーがないため，０を返す */
		return( 0 ) ;
	}
	s4StuckBorderAdjust = 1;
	s4NumBorderAdjust = 1 ;
	s4NumSize = 0 ;
	s4JustbeforeOffset = 0 ;
	s4StuckSize = 0 ;
	s4UsedBit = 0 ;
	astBitFlag = FALSE ;
	s4MaxNumSize = 0 ;
	s4DistributionSize = 0;
	s4BeforeNumBorderAdjust = 1;
//	s4_PreSize = 0;
//	s4_CurrSize = 0;
	while ( astParamChain != 0 ){
		/* 各メンバーの構造体先頭からのオフセットサイズ */
		s4_OffsetBit = 0;
//		s4_PreSize = 0;
//		s4_CurrSize = 0;
		s4_OffsetByte = s4StuckSize;/*配ったバイト数 */
		astSymDefInfo = stUniteChainAccess.parameter_sym.get( astParamChain);
		astTypeInfo = stSymbolInfoAccess.type.get( astSymDefInfo );
		ucKind = stTypeInfoAccess.typeKind.get(astTypeInfo);

		while ( ucKind== TYPEKIND_BITFIELD ){
			/* ビットフィールドの場合 */
			s4NumSize = stTypeInfoAccess.size.get( astTypeInfo );
			astTypeInfo = stTypeInfoAccess.elementType.get( astTypeInfo );
			/*  0 bit */
			if ( s4NumSize == 0 && s4NumBorderAdjust != 0 )	{
				if( stCoreEnvInfo.ucBit_zero_self )	{
					/* 0bitメンバの境界調整数を使うので、0ビットの境界調整数を取る */
					ccDeclGetVarSize( astTypeInfo, (U4 *)&s4NumBorderAdjust );
				}
				if ( astBitFlag == TRUE ){
					/* 0bitメンバの直前にビットフィールドがある場合のみ、有効になる */
					if( s4UsedBit % ( s4NumBorderAdjust * CHARBIT ) ){
						s4UsedBit += s4NumBorderAdjust * CHARBIT - s4UsedBit % ( s4NumBorderAdjust * CHARBIT );
					}
					s4_OffsetBit = s4UsedBit;
				}
			}else{
				s4BeforeNumBorderAdjust = s4NumBorderAdjust;
				ccDeclGetVarSize( astTypeInfo, (U4 *)&s4NumBorderAdjust );
				/* 最大の境界調整数を更新する */
				if ( s4NumBorderAdjust > s4StuckBorderAdjust){
					s4StuckBorderAdjust = s4NumBorderAdjust ;
				}
				/* 最大のメンバサイズを更新する */
				if( s4NumBorderAdjust > s4MaxNumSize ){
					s4MaxNumSize = s4NumBorderAdjust ;
				}
				/* １番目のビットフィールド */
				if( !astBitFlag){
					/* 1番目のビットフィールドなので、使われているビット数を０に */
					s4UsedBit = 0;
					if( s4StuckSize ){
						if( stCoreEnvInfo.ucBitByte_new_align  ){
							/* 新領域 */
							/*オフセットサイズが境界調整数の整数倍であるべき */
							s4StuckSize = (( s4StuckSize - 1 )/s4NumBorderAdjust + 1)*s4NumBorderAdjust;
							/* 先頭アドレスを保存しとく */
							s4JustbeforeOffset = s4StuckSize;
							s4_OffsetByte = s4StuckSize;
							s4_OffsetBit = 0;
							/* 構造体のサイズを増やす */
							s4StuckSize += s4NumBorderAdjust;
							/*総ビット数を計算 */
							s4DistributionSize = s4NumBorderAdjust * CHARBIT;
						}else{
							/* 普通のメンバと同じ先頭アドレスを共有できる*/
							/* 新領域 */
							/* 先頭アドレスを保存しとく */
							s4JustbeforeOffset = s4StuckSize;
							s4_OffsetByte = s4StuckSize;
							s4_OffsetBit = 0;
							/*オフセットサイズが境界調整数の整数倍であるべき */
							s4StuckSize = (( s4StuckSize - 1 )/s4NumBorderAdjust + 1)*s4NumBorderAdjust;
							s4DistributionSize = s4StuckSize - s4JustbeforeOffset;
							s4DistributionSize *= CHARBIT;/*総ビット数を計算 */
						}
					}else{
						/* 1番目のメンバ　新領域 */
						/* 先頭アドレスを保存しとく */
						s4_OffsetByte = 0;
						s4_OffsetBit = 0;
						/* 構造体のサイズを増やす */
						s4StuckSize = s4NumBorderAdjust;
						s4DistributionSize = s4NumBorderAdjust * CHARBIT;/*総ビット数を計算 */
					}
				}else{
					if( stCoreEnvInfo.ucBitBit_size_alignment  ){
						/* 同じサイズのビットを同じメモリ塊に配分する場合 */
						if( s4BeforeNumBorderAdjust != s4NumBorderAdjust )	{
							s4_OffsetBit += s4DistributionSize -  s4UsedBit;
							/* サイズが違うので、新領域に */
							s4StuckSize = (( s4StuckSize - 1 )/s4NumBorderAdjust + 1)*s4NumBorderAdjust;
							/* 新領域 */
							/* 先頭アドレスを保存しとく */
							s4JustbeforeOffset = s4StuckSize;
							/* 構造体のサイズを増やす */
							s4StuckSize += s4NumBorderAdjust ;
							s4DistributionSize = s4NumBorderAdjust * CHARBIT;/*総ビット数を計算 */
							s4UsedBit = 0;/* 1番目のビットフィールドなので、使われているビット数を０に */
						}
						/* サイズが同じ場合、何も変わらない */
					}else{
						/* 先頭アドレスを保存しとく */
						s4JustbeforeOffset = s4StuckSize;
						/*オフセットサイズが境界調整数の整数倍であるべき */
						s4StuckSize = (( s4StuckSize - 1 )/s4NumBorderAdjust + 1)*s4NumBorderAdjust;
						/*総ビット数を計算 */
						s4DistributionSize += (s4StuckSize - s4JustbeforeOffset)*CHARBIT;
					}
				}
				astBitFlag = TRUE ;
				/* 使うビット数 < 総ビット数 */
				if ( ( s4UsedBit + s4NumSize ) < ( s4DistributionSize  ) ){
					s4UsedBit += s4NumSize;
				}else if ( ( s4UsedBit + s4NumSize ) == ( s4DistributionSize  ) ){
					/* ちょうど*/
					s4JustbeforeOffset = s4StuckSize;
					s4DistributionSize = 0;
					s4UsedBit = 0 ;
				}else{
					if( stCoreEnvInfo.ucBit_divide ){
						s4NumSize -= s4DistributionSize - s4UsedBit;
					}else{
						s4_OffsetBit += s4DistributionSize - s4UsedBit;
					}
					/* 新領域 */
					s4JustbeforeOffset = s4StuckSize;
					s4StuckSize += s4NumBorderAdjust ;
					s4UsedBit = s4NumSize ;
					s4DistributionSize = s4NumBorderAdjust*CHARBIT;
				}
			}
			stSymbolInfoAccess.memOffset.set( astSymDefInfo, s4_OffsetByte );
			s4_OffsetBit += s4NumSize;
			astParamChain = stUniteChainAccess.next.get(astParamChain);
			astSymDefInfo = stUniteChainAccess.parameter_sym.get( astParamChain);
			astTypeInfo = stSymbolInfoAccess.type.get( astSymDefInfo );
			ucKind = stTypeInfoAccess.typeKind.get(astTypeInfo);
			continue;
		}

		if( !astParamChain ){
			break;
		}
		/* bit filed 以外*/
		astBitFlag = FALSE ;
		s4NumSize = ccDeclGetVarSize( astTypeInfo, (U4 *)&s4NumBorderAdjust );
		if ( s4NumBorderAdjust == 0 ){
			/* void　ありえない. 無視する　*/
			astParamChain = stUniteChainAccess.next.get(astParamChain);
			continue;
		}
		if( s4NumSize == 0 ){
			/* size　なし。ありえない。無視する */
			astParamChain = stUniteChainAccess.next.get(astParamChain);
			continue ;
		}
		/* 最大のメンバサイズを更新する */
		if( s4NumSize > s4MaxNumSize ){
			s4MaxNumSize = s4NumSize ;
		}
		/* 最大の境界調整数を更新する */
		if ( s4NumBorderAdjust > s4StuckBorderAdjust){
			s4StuckBorderAdjust = s4NumBorderAdjust;
		}
		if( s4StuckSize ){
			/*構造体サイズあり。つまり、前にメンバがある場合*/
			if( astBitFlag && (! stCoreEnvInfo.ucByteBit_new_align) ){
				/*その直前のメンバがビットフィールドであり、かつ、普通のメンバがビットフィールドの残った区間を使える場合 */
				/*使われたビット数をバイト数に変更する */
				s4StuckSize += (((s4UsedBit-1)/CHARBIT)+1);
			}
			/* 新メンバの先頭アドレスがその境界調整数の倍数であるべき */
			s4StuckSize = (( s4StuckSize - 1 )/s4NumBorderAdjust + 1)*s4NumBorderAdjust;
		}
		s4UsedBit = 0;
		s4_OffsetByte = s4StuckSize;
		/* 新メンバに領域を配る */
		while ( s4NumSize > 0 )	{
			s4StuckSize += s4NumBorderAdjust;
			s4JustbeforeOffset = s4StuckSize;
			s4NumSize -= s4NumBorderAdjust ;
		}
		stSymbolInfoAccess.memOffset.set( astSymDefInfo, s4_OffsetByte );
		astParamChain = stUniteChainAccess.next.get(astParamChain);
	}
	s4StuckSize = ( ( s4StuckSize - 1 ) / s4StuckBorderAdjust + 1 ) * s4StuckBorderAdjust ;

	if(pAlignment != NULL)
	{
		*pAlignment = s4StuckBorderAdjust ;
	}
	if( usKind == TYPEKIND_UNION )
	{
		return (s4MaxNumSize) ;
	}
	return (s4StuckSize) ;
}
static AST ccDeclStruct(U2 usKind, AST astTypeSpecifier ){
	AST	astCurBlockInfo ; 	/*現在のブロック情報*/
	AST	astTagNameInfo = 0 ;	/*タグ名情報*/
	AST	astBlockInfo ;		/*ブロック情報*/
	AST	astTypeInfo =0;		/*型情報*/
	U4   ulSize;
	U4	ulTmp;
	AST  astCurrToken;
	AST  astNextToken;
	U4  currTokenKind;
	U4  nextTokenKind;
	AST astParamChain;

	TRY;
	/* struct label {}  or union label {} */
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	astCurBlockInfo = CcBlockGetCurrInnermostOne();

	/*  tag名解析　*/
	if( currTokenKind == xLEX_SYMBOL ){
		astNextToken = CcLexGetRT(1);
		nextTokenKind = stLexTokenAccess.tokenKind.get( astNextToken );
		astTagNameInfo = CcBlockFindTag(stLexTokenAccess.name.get( astCurrToken ), &astBlockInfo);
		if (nextTokenKind == xLEX_OPENBLOCK){
			if( astBlockInfo != astCurBlockInfo ){
				astTagNameInfo = 0;
			}else if( astTagNameInfo != 0 ){
				astTypeInfo = stSymbolInfoAccess.type.get( astTagNameInfo );
				if( stTypeInfoAccess.memChain.get( astTypeInfo )
					|| (( usKind == TYPEDEF_UNION )&& !CcTypeIsUnion( astTypeInfo ) )
					|| (( usKind == TYPEDEF_STRUCT )&& !CcTypeIsStruct( astTypeInfo ) )){
					CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP,
							stLexTokenAccess.codeScp.get( astCurrToken ),
							stLexTokenAccess.name.get( astCurrToken ), NULL );
					CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP_1ST,
							stSymbolInfoAccess.codeScp.get( astTagNameInfo ),
							stLexTokenAccess.name.get( astCurrToken ), NULL );
					astTagNameInfo = 0;
					astTypeInfo = 0;

				}
			}
		}else if( nextTokenKind == xLEX_SEMICOLON){
			if( astTagNameInfo != 0 ){
				if( astBlockInfo == astCurBlockInfo ){
					CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP,
							stLexTokenAccess.codeScp.get( astCurrToken ),
							stLexTokenAccess.name.get( astCurrToken ), NULL );
					CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP_1ST,
							stSymbolInfoAccess.codeScp.get( astTagNameInfo ),
							stLexTokenAccess.name.get( astCurrToken ), NULL );
				}
			}
			astTagNameInfo = 0;
		}else{
			if( astTagNameInfo == 0 ){
				CcThrowWarning( CC_DECL_TAG_NOTFOUND,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}else{
				astTypeInfo = stSymbolInfoAccess.type.get( astTagNameInfo );
				if( usKind == TYPEDEF_UNION ){
					if( !CcTypeIsUnion( astTypeInfo )){
						CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP,
								stLexTokenAccess.codeScp.get( astCurrToken ),
								stLexTokenAccess.name.get( astCurrToken ), NULL );
						CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP_1ST,
								stSymbolInfoAccess.codeScp.get( astTagNameInfo ),
								stLexTokenAccess.name.get( astCurrToken ), NULL );
						astTagNameInfo = 0;
						astTypeInfo = 0;
					}
				}else{
					if( !CcTypeIsStruct( astTypeInfo )){
						CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP,
								stLexTokenAccess.codeScp.get( astCurrToken ),
								stLexTokenAccess.name.get( astCurrToken ), NULL );
						CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP_1ST,
								stSymbolInfoAccess.codeScp.get( astTagNameInfo ),
								stLexTokenAccess.name.get( astCurrToken ), NULL );
						astTagNameInfo = 0;
						astTypeInfo = 0;
					}
				}
			}
		}
		if (astTagNameInfo == 0)	{
			astTagNameInfo = CcBlockAddNewTag(astCurBlockInfo,
					stLexTokenAccess.name.get( astCurrToken ));
			stSymbolInfoAccess.codeScp.set( astTagNameInfo, stLexTokenAccess.codeScp.get( astCurrToken ));
		}else{
			astTypeInfo = stSymbolInfoAccess.type.get( astTagNameInfo );
		}
		astCurrToken = CcLexGetNextToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	}else{
		/* struct {  */
		astTagNameInfo = 0;
	}

	if (currTokenKind == xLEX_OPENBLOCK){
		/* 構造体/共用体型を作る */
		if ( astTagNameInfo == 0 ){
			astTagNameInfo = CcSymNewTagName( "" );
			astTypeInfo = 0;
			stSymbolInfoAccess.codeScp.set( astTagNameInfo, stLexTokenAccess.codeScp.get( astCurrToken ));
		}

		astParamChain = ccDeclStructField (  );
		stTypeSpecifierAccess.memberChain.set( astTypeSpecifier, astParamChain );
		astParamChain = ccDeclResolveMemChain(astParamChain);
		/* 構造体か共用体型のサイズを計算 */
		ulSize = ccDeclStUnSize( usKind, astParamChain, &ulTmp );
		if( astTypeInfo == 0 ){
			if( usKind == TYPEDEF_UNION ){
				astTypeInfo = CcTypeAddUnion(astTagNameInfo, astParamChain, ulSize);
			}else{
				astTypeInfo = CcTypeAddStruct( astTagNameInfo,  astParamChain, ulSize);
			}
			stTypeInfoAccess.bSizeUnDefined.set( astTypeInfo, FALSE );
			stSymbolInfoAccess.type.set( astTagNameInfo, astTypeInfo );
			stTypeSpecifierAccess.typeinfo.set( astTypeSpecifier, astTypeInfo );
		}else{
			stTypeInfoAccess.bSizeUnDefined.set( astTypeInfo, FALSE );
			CcTypeSetUnionStructInfo(astTypeInfo, astParamChain, ulSize );
		}
	}else if (astTagNameInfo != 0  ){
		if( astTypeInfo == 0 ){
			if( usKind == TYPEDEF_UNION ){
				astTypeInfo = CcTypeAddUnion( astTagNameInfo, 0, 0);
				stTypeInfoAccess.bSizeUnDefined.set( astTypeInfo, TRUE );
				stSymbolInfoAccess.type.set( astTagNameInfo, astTypeInfo );
				stTypeSpecifierAccess.typeinfo.set( astTypeSpecifier, astTypeInfo );
			}else{
				astTypeInfo = CcTypeAddStruct( astTagNameInfo, 0, 0);
				stTypeInfoAccess.bSizeUnDefined.set( astTypeInfo, TRUE );
				stSymbolInfoAccess.type.set( astTagNameInfo, astTypeInfo );
				stTypeSpecifierAccess.typeinfo.set( astTypeSpecifier, astTypeInfo );
			}
		}
	}else{
		/* struct の後にタグ名でもない，{ でもない */
		CcThrowWarning( CC_DECL_SYNTAX_ERROR,
			stLexTokenAccess.codeScp.get( astCurrToken ),
			stLexTokenAccess.name.get( astCurrToken ), NULL );
	}
	CATCH(astTagNameInfo);
	return astTagNameInfo;
}
static AST ccDeclAdjustEnumType( AST astEnumType, VARVALUE stMinValue, VARVALUE stMaxValue ){
	AST astTypeMaxValue;
	AST astTypeMinValue;
	VARVALUE   stTypeMaxValue, stTypeMinValue;
//	AST astZero;
	BOOL bSign = FALSE;
	astEnumType = CcTypeGetNoQualType(astEnumType );
	/*astZero =*/ CcValueGetZero( astEnumType );
	if( stMinValue.sign < 0 ){
		bSign = TRUE;
	}
	while( 1 ){
		astTypeMaxValue = CcValueGetMaxValue( astEnumType );
		astTypeMinValue = CcValueGetMinValue( astEnumType );
		stTypeMaxValue = CcValueGetInteger( astTypeMaxValue );
		stTypeMinValue = CcValueGetInteger( astTypeMinValue );
		if( ( stTypeMaxValue.sign > stMaxValue.sign
				|| stTypeMaxValue.u8Remainder >= stMaxValue.u8Remainder )
			&& ( stTypeMinValue.sign < stMinValue.sign
					|| stTypeMinValue.u8Remainder <= stMinValue.u8Remainder ) ){
			break;
		}
		switch(astEnumType){
		case TYPE_CHAR:
		case TYPE_SIGNED_CHAR:
			if(bSign){
				astEnumType = TYPE_SHORT;
			}else{
				astEnumType = TYPE_UNSIGNED_CHAR;
			}
			continue;
		case TYPE_UNSIGNED_CHAR:
			astEnumType = TYPE_SHORT;
			continue;
		case TYPE_SHORT:
			if(bSign){
				astEnumType = TYPE_INT;
			}else{
				astEnumType = TYPE_UNSIGNED_SHORT;
			}
			continue;
		case TYPE_UNSIGNED_SHORT:
			astEnumType = TYPE_INT;
			continue;
		case TYPE_INT:
			if(bSign){
				astEnumType = TYPE_LONG;
			}else{
				astEnumType = TYPE_UNSIGNED_INT;
			}
			continue;
		case TYPE_UNSIGNED_INT:
			astEnumType = TYPE_LONG;
			continue;
		case TYPE_LONG:
			if(bSign){
				astEnumType = TYPE_LONG_LONG;
			}else{
				astEnumType = TYPE_UNSIGNED_LONG;
			}
			continue;
		case TYPE_UNSIGNED_LONG:
			astEnumType = TYPE_LONG_LONG;
			continue;
		case TYPE_LONG_LONG:
			if(bSign){
				astEnumType = TYPE_UNSIGNED_LONG_LONG;
				break;
			}else{
				astEnumType = TYPE_UNSIGNED_LONG_LONG;
			}
			continue;
		default:
			break;
		}
		break;
	}
	return astEnumType;
}
static AST  ccDeclGetIntTypeForEnum( AST astDeclarationEnum ){
	VARVALUE stValue = { 0 };
	VARVALUE stMinValue = { 0 };
	VARVALUE stMaxValue = { 0 };
	AST astEnumType;
	AST	astValueExp ;		/* 定数式情報			*/
	AST astExpValue;
	AST	astDeclarator;
	AST astInitExpList;
	AST astConsInfo;
	AST astSymbol;
	BOOL bAdjust;
	if( astDeclarationEnum == 0 ){
		return 0;
	}
	if( stCoreEnvInfo.astEnumType != 0 ){
		/* 列挙型が指定された */
		astEnumType = stCoreEnvInfo.astEnumType;
		bAdjust = FALSE;
	}else{
		/* adjustable or shortenum の場合 */
		astEnumType = stCoreEnvInfo.astEnumBegin;
		bAdjust = TRUE;
	}
	if( bAdjust ){
		stValue.sign = 1;
		stValue.u8Remainder = 0;
		stMinValue = stValue;
		stMaxValue = stValue;
		while(astDeclarationEnum){
			astDeclarator = stDeclarationAccess.declarator.get( astDeclarationEnum );
			astSymbol = CcDeclGetSymfromDec( astDeclarator );
			if( DECLARATOR_INIT == stDeclaratorAccess.declaratorKind.get(astDeclarator) ){
				astInitExpList = stDeclaratorAccess.initialExpList.get( astDeclarator );
				astValueExp = stExpressionListAccess.expression.get(astInitExpList);
				astExpValue = stExpressionAccess.constValue.get(astValueExp);
			}else{
				astExpValue = 0;
			}
			/* 値がある場合 */
			if( astExpValue > 0 ){
				AST astType;
				astType = stValueInfoAccess.type.get( astExpValue );
				if( !CcTypeIsInteger(astType) ){
					CcThrowWarning( CC_DECL_ENUMCONST_INITEXP_WRONGTYPE,
						stDeclaratorAccess.codeScp.get( astDeclarator ),
						stSymbolInfoAccess.name.get( astSymbol ), NULL );
					astConsInfo = CcCalCastTo( astExpValue, astEnumType );
				}else{
					astConsInfo = astExpValue;
				}
			}else{
				astConsInfo = 0;
			}

			/* 列挙定数の値を作成 */
			if( astConsInfo == 0 ){
				stValue.u8Remainder++;
				if( stValue.u8Remainder == 0 ){
					CcThrowWarning( CC_DECL_ENUMCONST_INITEXP_OVERFLOW,
						stDeclaratorAccess.codeScp.get( astDeclarator ),
						stSymbolInfoAccess.name.get( astSymbol ), NULL );
				}
			}else{
				stValue = CcValueGetInteger( astConsInfo );
			}
			if( stMinValue.sign > stValue.sign || stMinValue.u8Remainder > stValue.u8Remainder ){
				stMinValue = stValue;
			}
			if( stMaxValue.sign < stValue.sign || stMaxValue.u8Remainder < stValue.u8Remainder ){
				stMaxValue = stValue;
			}
			astDeclarationEnum = stDeclarationAccess.next.get( astDeclarationEnum );
		}
		astEnumType = ccDeclAdjustEnumType( astEnumType, stMinValue, stMaxValue );
	}
	return astEnumType;
}
static AST ccDeclGetEnumConstChain( AST astDeclarationEnum, AST astEnumType ){
	AST astHeaderChain=0;
	AST astPreChain = 0;
	AST astCurrChain = 0;
	AST astValue;
	AST astDeclarator;
	AST astInitExpList;
	AST astValueExp;
	AST astExpValue;
	AST astConsInfo;
	AST astEnumSym=0;

	astValue = CcValueGetZero( astEnumType );
	while(astDeclarationEnum){
		astDeclarator = stDeclarationAccess.declarator.get( astDeclarationEnum );
		/*debug,13/1/23,S*/
		if( stDeclaratorAccess.declaratorKind.get(astDeclarator) == DECLARATOR_SYM ){
			astEnumSym = stDeclaratorAccess.symbol.get(astDeclarator);
		}
		/*debug,13/1/23,E*/
		if( DECLARATOR_INIT == stDeclaratorAccess.declaratorKind.get(astDeclarator) ){
			astInitExpList = stDeclaratorAccess.initialExpList.get( astDeclarator );
			astValueExp = stExpressionListAccess.expression.get(astInitExpList);
			astExpValue = stExpressionAccess.constValue.get(astValueExp);
			/*debug,13/1/23,S*/
			astDeclarator = stDeclaratorAccess.childDeclarator.get(astDeclarator);
			if( stDeclaratorAccess.declaratorKind.get(astDeclarator) == DECLARATOR_SYM ){
				astEnumSym = stDeclaratorAccess.symbol.get(astDeclarator);
			}else{
				astEnumSym = 0;
			}
			/*debug,13/1/23,E*/
		}else{
			astExpValue = 0;
		}
		/* 値がある場合 */
		if( astExpValue > 0 ){
			astConsInfo = CcCalCastTo( astExpValue, astEnumType );
		}else{
			astConsInfo = 0;
		}
		/* 列挙定数の値を作成 */
		if( astConsInfo == 0 ){
			astValue = CcCalAdditive( astValue, CcValueGetOne( astEnumType ), astEnumType );
		}else{
			astValue = astConsInfo;
		}
		stSymbolInfoAccess.value.set( astEnumSym, astValue );
		stSymbolInfoAccess.type.set( astEnumSym, astEnumType );

		stUniteChainAccess.alloc(1);
		astCurrChain = stUniteChainAccess.getMax();
		stUniteChainAccess.parameter_sym.set( astCurrChain, astEnumSym );
		if( astPreChain == 0 ){
			astHeaderChain = astCurrChain;
		}else{
			stUniteChainAccess.next.set( astPreChain, astCurrChain );
			stUniteChainAccess.before.set( astCurrChain, astPreChain );
		}
		astPreChain = astCurrChain;
		astDeclarationEnum = stDeclarationAccess.next.get( astDeclarationEnum );
	}
	return astHeaderChain;
}

static VOID ccDeclSetEnumTypeInfo(AST astTypeInfo, AST astDeclarationEnum ){
	AST astEnumType;
	AST astHeaderChain=0;

	astEnumType = ccDeclGetIntTypeForEnum(astDeclarationEnum);
	astHeaderChain = ccDeclGetEnumConstChain( astDeclarationEnum, astEnumType );
	while( astTypeInfo ){
		stTypeInfoAccess.copy( astEnumType, astTypeInfo, 1 );
		stTypeInfoAccess.next.set( astTypeInfo, 0 );
		stTypeInfoAccess.memChain.set( astTypeInfo, astHeaderChain );
		stTypeInfoAccess.typeKind.set( astTypeInfo, TYPEKIND_ENUM );
		astTypeInfo = stTypeInfoAccess.next.get( astTypeInfo );
	}

}
static AST ccDeclCreateEnumType( AST astDeclarationEnum ){
	AST astEnumType;
	AST astHeaderChain=0;
	AST astEnumTypeIndex;

	astEnumType = ccDeclGetIntTypeForEnum(astDeclarationEnum);
	astHeaderChain = ccDeclGetEnumConstChain( astDeclarationEnum, astEnumType );
	astEnumTypeIndex = CcTypeAddEnum( 0, astEnumType, astHeaderChain );
	/* 列挙定数のシンボル情報を列挙体型に繋ぐ */
	return astEnumTypeIndex;
}

/*debug,13/1/23,S*/
static AST ccDeclEnumField ( AST typeSpecifier ){
/*debug,13/1/23,E*/
	AST	astCurBlockInfo ;	/* 現在のブロック情報  	*/
	AST	astEnumSym ;			/* 列挙定数情報		*/
	U4	u4EndChar[3]={ xLEX_COMMA, xLEX_CLOSEBLOCK, xLEX_UNDEFINED } ;		/* 終了文字配列		*/
	AST	astValueExp ;		/* 定数式情報			*/
	AST	astDeclarationEnum ; /* 列挙定数宣言子		*/
	AST	astDeclaratorEnum ; /* 列挙定数宣言子		*/
	AST	astPreDeclarationInfo ;	/* 直前の宣言子情報 */
	AST	astInitEnumDeclaratorInfo ; /*初期化付き列挙定数宣言子情報*/
	AST	astInitExpList ;	/* 初期化式情報		*/

	AST  astCurrToken;
	U4   currTokenKind;
	AST  firstScp, secondScp;
	/*debug,13/1/23,S*/
	AST  astResult=0;
	/*debug,13/1/23,E*/

	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	astCurBlockInfo = CcBlockGetCurrInnermostOne();
	astPreDeclarationInfo = 0 ;
	while (currTokenKind != xLEX_CLOSEBLOCK && currTokenKind != xLEX_ENDOFFILE ){
		if (currTokenKind != xLEX_SYMBOL){
			/* タグ名のメンバーは未定義 */
			CcThrowWarning( CC_DECL_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
			/* エラーが起きたので，宣言の区切り子とみなすトークンまで読み捨てる */
			while( currTokenKind != xLEX_SEMICOLON
					&& currTokenKind != xLEX_COMMA
					&& currTokenKind != xLEX_SYMBOL
					&& currTokenKind != xLEX_CLOSEBLOCK
					&& currTokenKind != xLEX_ENDOFFILE ){
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			}
			if( currTokenKind == xLEX_SEMICOLON
					|| currTokenKind == xLEX_CLOSEBLOCK
					|| currTokenKind == xLEX_ENDOFFILE ){
				/* 列挙定数の宣言が終わる */
				break;
			}
			if( currTokenKind == xLEX_COMMA ){
				/* ,の場合，次の列挙定数を見る */
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
				continue;
			}
		}
		/* 列挙定数ごとに  */
		stDeclarationAccess.alloc(1);
		astDeclarationEnum = stDeclarationAccess.getMax();
		stDeclaratorAccess.alloc(1);
		astDeclaratorEnum = stDeclaratorAccess.getMax();
		astEnumSym = CcBlockAddNewEnumSymbol( astCurBlockInfo, stLexTokenAccess.name.get( astCurrToken ));

		firstScp = stLexTokenAccess.codeScp.get(astCurrToken);
		stDeclarationAccess.declarator.set( astDeclarationEnum, astDeclaratorEnum );
		stDeclarationAccess.parentKind.set( astDeclarationEnum, KIND_TYPESPECIFIER );
		/*debug,13/1/23,S*/
		stDeclarationAccess.parentIdx.set( astDeclarationEnum, typeSpecifier );
		/*debug,13/1/23,E*/
		stDeclaratorAccess.declaratorKind.set( astDeclaratorEnum, xDECLARATOR_SYM );
		stDeclaratorAccess.declaration.set( astDeclaratorEnum, astDeclarationEnum );
		stDeclaratorAccess.codeScp.set( astDeclaratorEnum, firstScp);

		/* 列挙定数のシンボル情報  */
		stDeclaratorAccess.symbol.set( astDeclaratorEnum, astEnumSym );
		stSymbolInfoAccess.codeScp.set( astEnumSym, firstScp );


		/* 列挙定数をカレントブロックに繋ぐ */
		astCurrToken = CcLexGetNextToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

		/* 列挙定数の値を指定していない場合，この宣言子情報が完成されたので，宣言情報に繋ぐ */
		if  ( astPreDeclarationInfo != 0 ){
			stDeclarationAccess.next.set( astPreDeclarationInfo, astDeclarationEnum );
		}else{
			/*debug,13/1/23,S*/
			astResult = astDeclarationEnum;
			/*debug,13/1/23,E*/
		}
		/*debug,12/11/15,S*/
		astPreDeclarationInfo = astDeclarationEnum ;
		/*debug,12/11/15,E*/

		if( currTokenKind == xLEX_EQU ){
			astCurrToken = CcLexGetNextToken();
			/* 値が指定された場合，初期化宣言子とみなし，該当する初期化宣言子の情報を作成する */
			stDeclaratorAccess.alloc(1);
			astInitEnumDeclaratorInfo = stDeclaratorAccess.getMax();
			stDeclarationAccess.declarator.set( astDeclarationEnum, astInitEnumDeclaratorInfo );

			stDeclaratorAccess.childDeclarator.set(astInitEnumDeclaratorInfo, astDeclaratorEnum);
			stDeclaratorAccess.parentDeclarator.set(astDeclaratorEnum, astInitEnumDeclaratorInfo);

			astValueExp = CcConstantExpression( u4EndChar, KIND_DECLARATOR, astInitEnumDeclaratorInfo );
			if( astValueExp >= MIN_ARRAY ){
				/* 値指定の定数式を初期化式とみなす */
				stExpressionListAccess.alloc(1);
				astInitExpList = stExpressionListAccess.getMax();

				stExpressionListAccess.parameterKind.set(astInitExpList, KIND_EXPRESSIONINFO);
				stExpressionListAccess.parentKind.set( astInitExpList, astInitEnumDeclaratorInfo  );
				stExpressionListAccess.parent.set(astInitExpList, astInitEnumDeclaratorInfo );
				stExpressionListAccess.expression.set( astInitExpList, astValueExp );
				stDeclaratorAccess.initialExpList.set( astInitEnumDeclaratorInfo, astInitExpList );

				secondScp = stExpressionAccess.codeScp.get(astValueExp);
				stExpressionListAccess.codeScp.set(astInitExpList, secondScp);
			}else{
				astCurrToken = CcLexGetCurrToken();
				CcThrowWarning( CC_DECL_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}
			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			secondScp = stLexTokenAccess.codeScp.get(CcLexGetLF(1));
			secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stDeclaratorAccess.codeScp.set(astInitEnumDeclaratorInfo, secondScp );
		}

		secondScp = stLexTokenAccess.codeScp.get(CcLexGetLF(1));
		secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
		stDeclarationAccess.codeScp.set(astDeclarationEnum, secondScp );
		if( currTokenKind == xLEX_COMMA ){
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			continue ;
		}else if ( currTokenKind == xLEX_CLOSEBLOCK){
			break;
		}
	}

	if( currTokenKind == xLEX_CLOSEBLOCK ){
		astCurrToken = CcLexGetNextToken();
	}

	/*debug,13/1/23,S*/
	return astResult;
	/*debug,13/1/23,E*/
}
static AST  ccDeclEnum( AST typeSpecifier ){
	AST	astCurBlockInfo ;	/*現在のブロック情報*/
	AST	astTagNameInfo=0 ;	/*タグ名情報*/
	AST	astBlockInfo ;		/*ブロック情報*/
	AST	astTypeInfo =0 ;		/*型情報*/
	AST  astCurrToken;
	AST  astNextToken;
	U4  currTokenKind;
	U4  nextTokenKind;
	AST astParamChain;

	TRY;
	/*  enum label { ... }  */
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	astCurBlockInfo = CcBlockGetCurrInnermostOne();

	/*tag名解析*/
	if(currTokenKind == xLEX_SYMBOL){
		astNextToken = CcLexGetRT(1);
		nextTokenKind = stLexTokenAccess.tokenKind.get( astNextToken );
		astTagNameInfo = CcBlockFindTag(stLexTokenAccess.name.get( astCurrToken ), &astBlockInfo);
		if (nextTokenKind == xLEX_OPENBLOCK){
			if( astBlockInfo != astCurBlockInfo ){
				astTagNameInfo = 0;
			}else if( astTagNameInfo != 0 ){
				astTypeInfo = stSymbolInfoAccess.type.get( astTagNameInfo );
				if( stTypeInfoAccess.memChain.get( astTypeInfo )
					|| !CcTypeIsEnum( astTypeInfo )){

					CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP,
							stLexTokenAccess.codeScp.get( astCurrToken ),
							stLexTokenAccess.name.get( astCurrToken ), NULL );
					CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP_1ST,
							stSymbolInfoAccess.codeScp.get( astTagNameInfo ),
							stLexTokenAccess.name.get( astCurrToken ), NULL );
					astTagNameInfo = 0;
					astTypeInfo = 0;
				}
			}
		}else if (nextTokenKind == xLEX_SEMICOLON){
			if( astTagNameInfo != 0 ){
				if( astBlockInfo == astCurBlockInfo ){
					CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP,
							stLexTokenAccess.codeScp.get( astCurrToken ),
							stLexTokenAccess.name.get( astCurrToken ), NULL );
					CcThrowWarning( CC_DECL_TAG_INBLOCK_OVERLAP_1ST,
							stSymbolInfoAccess.codeScp.get( astTagNameInfo ),
							stLexTokenAccess.name.get( astCurrToken ), NULL );
				}
			}
			astTagNameInfo = 0 ;
		}else{
			astTypeInfo = stSymbolInfoAccess.type.get( astTagNameInfo );
			if( astTagNameInfo == 0 || !CcTypeIsEnum( astTypeInfo ) ){
				CcThrowWarning( CC_DECL_TAG_NOTFOUND,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
				astTagNameInfo = 0;
				astTypeInfo = 0;
			}
		}
		if (astTagNameInfo == 0)	{
			astTagNameInfo = CcBlockAddNewTag(astCurBlockInfo,
					stLexTokenAccess.name.get( astCurrToken ));
			stSymbolInfoAccess.codeScp.set( astTagNameInfo, stLexTokenAccess.codeScp.get( astCurrToken ));
			astTypeInfo = 0;
		}else{
			astTypeInfo = stSymbolInfoAccess.type.get( astTagNameInfo );
		}
		astCurrToken = CcLexGetNextToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	}else{
		astTagNameInfo = 0;
	}

	if ( currTokenKind == xLEX_OPENBLOCK ){
		if ( astTagNameInfo == 0 ){
			astTagNameInfo = CcSymNewTagName( "" );
			astTypeInfo = 0;
			stSymbolInfoAccess.codeScp.set( astTagNameInfo, stLexTokenAccess.codeScp.get( astCurrToken ));
		}

		/*debug,13/1/23,S*/
		astParamChain = ccDeclEnumField ( typeSpecifier );
		/*debug,13/1/23,E*/
		stTypeSpecifierAccess.memberChain.set( typeSpecifier, astParamChain );
		/* 構造体か共用体型のサイズを計算 */
		if( astTypeInfo == 0 ){
			astTypeInfo =  ccDeclCreateEnumType(astParamChain);
			stSymbolInfoAccess.type.set( astTagNameInfo, astTypeInfo );
		}else{
			ccDeclSetEnumTypeInfo(astTypeInfo, astParamChain );
		}
		stTypeInfoAccess.tagInfo.set( astTypeInfo, astTagNameInfo );
		stTypeSpecifierAccess.typeinfo.set( typeSpecifier, astTypeInfo );
	}else if (astTagNameInfo != 0 && astTypeInfo == 0 ){
		if( astTypeInfo == 0 ){
			astTypeInfo = CcTypeAddDefaultEnum( astTagNameInfo );
			stSymbolInfoAccess.type.set( astTagNameInfo, astTypeInfo );
			stTypeSpecifierAccess.typeinfo.set( typeSpecifier, astTypeInfo );
		}
	}else{
		/* neither "enum label" nor "enum {...} */
		CcThrowWarning( CC_DECL_SYNTAX_ERROR,
			stLexTokenAccess.codeScp.get( astCurrToken ),
			stLexTokenAccess.name.get( astCurrToken ), NULL );
	}
	CATCH(astTagNameInfo);
	return astTagNameInfo	;
}
static VOID ccDeclCollectStorageClass( AST astTypeSpec ){
	AST astCurrToken;
	U4  currTokenKind;
	U2  RetUshort;

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	switch( currTokenKind ){
		case  xLEX_EXTERN:{
			RetUshort = stTypeSpecifierAccess.externNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.externNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_AUTO:{
			RetUshort = stTypeSpecifierAccess.autoNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.autoNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_STATIC:{
			RetUshort = stTypeSpecifierAccess.staticNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.staticNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_REGISTER:{
			RetUshort = stTypeSpecifierAccess.registerNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.registerNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_TYPEDEF:{
			RetUshort = stTypeSpecifierAccess.typedefNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.typedefNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
	}
}
static VOID ccDeclCollectTypeQualifier( AST astTypeSpec ){
	AST astCurrToken;
	U4  currTokenKind;
	U2  RetUshort;

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	switch( currTokenKind ){
		case  xLEX_CONST:{
			RetUshort = stTypeSpecifierAccess.constNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.constNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_VOLATILE:{
			RetUshort = stTypeSpecifierAccess.volatileNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.volatileNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_RESTRICT:{
			RetUshort = stTypeSpecifierAccess.restrictNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.restrictNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
	}
}
static VOID ccDeclCollectExtendQualifier( AST astTypeSpec ){
	AST astCurrToken;
	U4  currTokenKind;
	U2  RetUshort;

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	switch( currTokenKind ){
		case  xLEX_INTERRUPT:{
			RetUshort = stTypeSpecifierAccess.interruptNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.interruptNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case	xLEX_INLINE:{
			RetUshort = stTypeSpecifierAccess.inlineNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.inlineNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_INLINEASM:{
			RetUshort = stTypeSpecifierAccess.asmNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.asmNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_NEAR:{
			RetUshort = stTypeSpecifierAccess.nearNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.nearNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_FAR:{
			RetUshort = stTypeSpecifierAccess.farNum.get( astTypeSpec );
			RetUshort++;
			stTypeSpecifierAccess.farNum.set( astTypeSpec, RetUshort );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
	}
}
static VOID ccDeclCollectBasicType( AST astTypeSpec ){
	AST astCurrToken;
	AST astType;
	U4  currTokenKind;
	U2  RetUshort;
	U2  specifierKind = 0;
	specifierKind = stTypeSpecifierAccess.specifyKind.get( astTypeSpec );
	astType = stTypeSpecifierAccess.typeinfo.get(astTypeSpec);
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	switch( currTokenKind ){
		case xLEX_SIGNED:{
			if( specifierKind == 0 || specifierKind == TYPEDEF_BASE ){
				specifierKind = TYPEDEF_BASE;
				RetUshort = stTypeSpecifierAccess.signNum.get( astTypeSpec );
				RetUshort++;
				stTypeSpecifierAccess.signNum.set( astTypeSpec, RetUshort );
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "signed", NULL  );
			}
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case xLEX_UNSIGNED:{
			if( specifierKind == 0 || specifierKind == TYPEDEF_BASE ){
				specifierKind = TYPEDEF_BASE;
				RetUshort = stTypeSpecifierAccess.unsigneNum.get( astTypeSpec );
				RetUshort++;
				stTypeSpecifierAccess.unsigneNum.set( astTypeSpec, RetUshort );
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "unsigned", NULL  );
			}
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case xLEX_LONG:{
			if( specifierKind == 0 || specifierKind == TYPEDEF_BASE ){
				specifierKind = TYPEDEF_BASE;
				RetUshort = stTypeSpecifierAccess.longNum.get( astTypeSpec );
				RetUshort++;
				stTypeSpecifierAccess.longNum.set( astTypeSpec, RetUshort );
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "long", NULL  );
			}
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case xLEX_SHORT:{
			if( specifierKind == 0 || specifierKind == TYPEDEF_BASE ){
				specifierKind = TYPEDEF_BASE;
				RetUshort = stTypeSpecifierAccess.shortNum.get( astTypeSpec );
				RetUshort++;
				stTypeSpecifierAccess.shortNum.set( astTypeSpec, RetUshort );
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "short", NULL  );
			}
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_VOID	:{
			if( specifierKind == 0 ){
				specifierKind = TYPEDEF_BASE;
				astType = TYPE_VOID;
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "void", NULL  );
			}
			stTypeSpecifierAccess.specifyKind.set( astTypeSpec, specifierKind );
			stTypeSpecifierAccess.typeinfo.set( astTypeSpec, astType );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_CHAR:{
			if( ( astType == 0 )
					&&( specifierKind == 0 || specifierKind == TYPEDEF_BASE ) ){
				specifierKind = TYPEDEF_BASE;
				astType =  TYPE_CHAR;
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "char", NULL  );
			}
			stTypeSpecifierAccess.specifyKind.set( astTypeSpec, specifierKind );
			stTypeSpecifierAccess.typeinfo.set( astTypeSpec, astType );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
		case  xLEX_INT	:{
			if( ( astType == 0 )
					&&( specifierKind == 0 || specifierKind == TYPEDEF_BASE ) ){
				specifierKind = TYPEDEF_BASE;
				astType =  TYPE_INT;
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "int", NULL  );
			}
			stTypeSpecifierAccess.specifyKind.set( astTypeSpec, specifierKind );
			stTypeSpecifierAccess.typeinfo.set( astTypeSpec, astType );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}

		case  xLEX_FLOAT:{
			if( ( astType == 0 )
					&&( specifierKind == 0 || specifierKind == TYPEDEF_BASE ) ){
				specifierKind = TYPEDEF_BASE;
				astType =  TYPE_FLOAT;
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "float", NULL  );
			}
			stTypeSpecifierAccess.specifyKind.set( astTypeSpec, specifierKind );
			stTypeSpecifierAccess.typeinfo.set( astTypeSpec, astType );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}

		case  xLEX_DOUBLE:{
			if( ( astType == 0 )
					&&( specifierKind == 0 || specifierKind == TYPEDEF_BASE ) ){
				specifierKind = TYPEDEF_BASE;
				astType =  TYPE_DOUBLE;
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "double", NULL  );
			}
			stTypeSpecifierAccess.specifyKind.set( astTypeSpec, specifierKind );
			stTypeSpecifierAccess.typeinfo.set( astTypeSpec, astType );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break;
		}
	}

	stTypeSpecifierAccess.specifyKind.set( astTypeSpec, specifierKind );
	stTypeSpecifierAccess.typeinfo.set( astTypeSpec, astType );
}
static VOID ccDeclCollectCompoundType( AST astTypeSpec ){
	AST astCurrToken;
	AST astType=0;
	AST astTagSymInfo;
	U4  currTokenKind;
	U2  specifierKind = 0;
	specifierKind = stTypeSpecifierAccess.specifyKind.get( astTypeSpec );
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	TRY;
	switch( currTokenKind ){
		case  xLEX_ENUM	:{
			if(specifierKind == 0){
				specifierKind = TYPEDEF_ENUM;
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "enum", NULL  );
			}
			astTagSymInfo = ccDeclEnum( astTypeSpec );
			stTypeSpecifierAccess.symbol.set( astTypeSpec, astTagSymInfo );
			astType = stSymbolInfoAccess.type.get( astTagSymInfo );
			stTypeSpecifierAccess.specifyKind.set( astTypeSpec, specifierKind );
			stTypeSpecifierAccess.typeinfo.set( astTypeSpec, astType );
			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break ;
		}
		case  xLEX_STRUCT:{
			if(specifierKind == 0){
				specifierKind = TYPEDEF_STRUCT;
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "struct", NULL  );
			}
			astTagSymInfo = ccDeclStruct( TYPEDEF_STRUCT, astTypeSpec );
			stTypeSpecifierAccess.symbol.set( astTypeSpec, astTagSymInfo );
			astType = stSymbolInfoAccess.type.get( astTagSymInfo );
			stTypeSpecifierAccess.specifyKind.set( astTypeSpec, specifierKind );
			stTypeSpecifierAccess.typeinfo.set( astTypeSpec, astType );
			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break ;
		}
		case  xLEX_UNION:{
			if(specifierKind == 0){
				specifierKind = TYPEDEF_UNION;
			}else{
				CcThrowWarning( CC_DECL_SPECIFIER_ILLEGAL,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					 "union", NULL  );
			}
			astTagSymInfo = ccDeclStruct( TYPEDEF_UNION, astTypeSpec );
			stTypeSpecifierAccess.symbol.set( astTypeSpec, astTagSymInfo );
			astType = stSymbolInfoAccess.type.get( astTagSymInfo );
			stTypeSpecifierAccess.specifyKind.set( astTypeSpec, specifierKind );
			stTypeSpecifierAccess.typeinfo.set( astTypeSpec, astType );
			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			break ;
		}
	}

	CATCH((VOID)0);
}
static VOID ccDeclTryTypedefSymbol( AST astTypeSpec, UCHAR ucNameSpace ){
	AST astCurrToken;
	AST astType;
	AST astSymInfo;
	AST astDefBlock=0;
	U4  currTokenKind;
	U2  RetUshort;
	U2  specifierKind = 0;
	specifierKind = stTypeSpecifierAccess.specifyKind.get( astTypeSpec );
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( xLEX_SYMBOL == currTokenKind ){
		/* find the definition */
		astSymInfo = CcBlockFindSymbol( stLexTokenAccess.name.get( astCurrToken ), &astDefBlock );
        if( astSymInfo >= MIN_ARRAY ){
        	/* found */
        	RetUshort = stSymbolInfoAccess.symClass.get( astSymInfo );
        	if( RetUshort == CLASS_TYPEDEF ){
        		/* typedef symbol */
				if(specifierKind == 0){
					specifierKind = TYPEDEF_TYPEDEF;
					stTypeSpecifierAccess.symbol.set( astTypeSpec, astSymInfo );
					astType = stSymbolInfoAccess.type.get( astSymInfo );
					astCurrToken = CcLexGetNextToken();
					stTypeSpecifierAccess.specifyKind.set( astTypeSpec, specifierKind );
					stTypeSpecifierAccess.typeinfo.set( astTypeSpec, astType );
				}else{
					/* type duplicate  */
					switch (ucNameSpace){
					case xNAMESPACE_ARG:
						/* treat as parameter name instead of typedef symbol */
						CcThrowWarning( CC_DECL_FUNC_PARAM_DUPLICATE_TYPEDEF,
								stSymbolInfoAccess.codeScp.get( astCurrToken ),
							stLexTokenAccess.name.get( astCurrToken ), NULL  );
						CcThrowWarning( CC_DECL_FUNC_PARAM_DUPLICATE_TYPEDEF,
							stLexTokenAccess.codeScp.get( astCurrToken ),
							stLexTokenAccess.name.get( astCurrToken ), NULL  );
						break;
					case xNAMESPACE_ORD:{
						AST astCurrBlockInfo;
						astCurrBlockInfo = CcBlockGetCurrInnermostOne();
						if( astCurrBlockInfo != astDefBlock ){
							/* treat as variable name which is in inner block instead of typedef symbol */
							CcThrowWarning( CC_DECL_TEMPORARY_DUPLICATE_TYPEDEF,
									stSymbolInfoAccess.codeScp.get( astCurrToken ),
								stLexTokenAccess.name.get( astCurrToken ), NULL  );
							CcThrowWarning( CC_DECL_TEMPORARY_DUPLICATE_TYPEDEF1ST,
								stLexTokenAccess.codeScp.get( astCurrToken ),
								stLexTokenAccess.name.get( astCurrToken ), NULL  );
						}
						break;
					}
					case xNAMESPACE_MEM:
						/* treat as member name instead of typedef symbol */
						CcThrowWarning( CC_DECL_MEMBER_DUPLICATE_TYPEDEF,
								stSymbolInfoAccess.codeScp.get( astCurrToken ),
							stLexTokenAccess.name.get( astCurrToken ), NULL  );
						CcThrowWarning( CC_DECL_MEMBER_DUPLICATE_TYPEDEF1ST,
							stLexTokenAccess.codeScp.get( astCurrToken ),
							stLexTokenAccess.name.get( astCurrToken ), NULL  );
						break;
					case xNAMESPACE_TYPENAME:
						break;
					}
				}
        	}
        }
	}
}
static VOID ccDeclResolveTypeSpeicifer( AST typeSpecifier ){
	AST  astBaseType;
	AST  astElementType;
	U2 qualifier = 0;
	U2 newqualifier = 0;
	U2 constCounter = 0;
	U2 volatileCounter = 0;
	U2 restrictCounter = 0;
	U2 spKind = stTypeSpecifierAccess.specifyKind.get( typeSpecifier );

	astBaseType = stTypeSpecifierAccess.typeinfo.get( typeSpecifier );
	if( spKind == 0 ){
		spKind = TYPEDEF_BASE;
		stTypeSpecifierAccess.specifyKind.set( typeSpecifier, TYPEDEF_BASE );
		astBaseType = TYPE_INT;
		CcThrowWarning( CC_DECL_SPECIFIER_NOTFOUND,
			stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
			NULL, NULL  );
	}else if( TYPEDEF_BASE == spKind ){
		/*debug,12/10/03,S*/
		if( astBaseType == 0 ){
			astBaseType = TYPE_INT;
		}
		/*debug,12/10/03,E*/
		U2 signedFlag = stTypeSpecifierAccess.signNum.get( typeSpecifier );
		U2 unsignedFlag = stTypeSpecifierAccess.unsigneNum.get( typeSpecifier );
		U2 shortFlag = stTypeSpecifierAccess.shortNum.get( typeSpecifier );
		U2 longFlag = stTypeSpecifierAccess.longNum.get( typeSpecifier );
		switch( astBaseType ){
		case TYPE_VOID:
			if( signedFlag + unsignedFlag + shortFlag + longFlag > 0 ){
				CcThrowWarning( CC_DECL_SPECIFIER_INEXISTENCE,
					stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
					NULL, NULL  );
			}
			break;
		case TYPE_CHAR:
			if( shortFlag + longFlag > 0 ){
				CcThrowWarning( CC_DECL_SPECIFIER_INEXISTENCE,
					stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
					NULL, NULL  );
			}
			if( signedFlag + unsignedFlag > 1 ){
				CcThrowWarning( CC_DECL_SPECIFIER_INEXISTENCE,
					stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
					NULL, NULL  );
			}
			if( signedFlag ){
				astBaseType = TYPE_SIGNED_CHAR;
			}
			if( unsignedFlag ){
				astBaseType = TYPE_UNSIGNED_CHAR;
			}
			break;
		case TYPE_INT:
			if( shortFlag > 1 || longFlag > 2 || (shortFlag>0 && longFlag>0) ){
				CcThrowWarning( CC_DECL_SPECIFIER_INEXISTENCE,
					stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
					NULL, NULL  );
			}
			if( signedFlag + unsignedFlag > 1 ){
				CcThrowWarning( CC_DECL_SPECIFIER_INEXISTENCE,
					stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
					NULL, NULL  );
			}
			if( longFlag > 1 ){
				if( signedFlag ){
					astBaseType = TYPE_SIGNED_LONG_LONG;
				}else if( unsignedFlag ){
					astBaseType = TYPE_UNSIGNED_LONG_LONG;
				}else{
					astBaseType = TYPE_LONG_LONG;
				}
			}else if( longFlag > 0 ){
				if( signedFlag ){
					astBaseType = TYPE_SIGNED_LONG;
				}else if( unsignedFlag ){
					astBaseType = TYPE_UNSIGNED_LONG;
				}else{
					astBaseType = TYPE_LONG;
				}
			}else if( shortFlag > 0 ){
				if( signedFlag ){
					astBaseType = TYPE_SIGNED_SHORT;
				}else if( unsignedFlag ){
					astBaseType = TYPE_UNSIGNED_SHORT;
				}else{
					astBaseType = TYPE_SHORT;
				}
			}else{
				if( signedFlag ){
					astBaseType = TYPE_SIGNED_INT;
				}else if( unsignedFlag ){
					astBaseType = TYPE_UNSIGNED_INT;
				}else{
					astBaseType = TYPE_INT;
				}
			}
			break;
		case TYPE_FLOAT:
			if( shortFlag + longFlag > 0 ){
				CcThrowWarning( CC_DECL_SPECIFIER_INEXISTENCE,
					stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
					NULL, NULL  );
			}
			if( signedFlag + unsignedFlag > 0 ){
				CcThrowWarning( CC_DECL_SPECIFIER_INEXISTENCE,
					stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
					NULL, NULL  );
			}
			break;
		case TYPE_DOUBLE:
			if( shortFlag > 0 || longFlag > 1 ){
				CcThrowWarning( CC_DECL_SPECIFIER_INEXISTENCE,
					stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
					NULL, NULL  );
			}
			if( signedFlag + unsignedFlag > 0 ){
				CcThrowWarning( CC_DECL_SPECIFIER_INEXISTENCE,
					stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
					NULL, NULL  );
			}
			if( longFlag ){
				astBaseType = TYPE_LONG_DOUBLE;
			}
			break;
		}
	}
	qualifier = stTypeInfoAccess.typeQual.get( astBaseType );
	/*  const duplicate check  */
	if( CcTypeIsConst( qualifier) ){
		constCounter = 1;
	}
	constCounter += stTypeSpecifierAccess.constNum.get( typeSpecifier );
	if( constCounter > 1 ){
		CcThrowWarning( CC_DECL_QUALIFIER_OVERLAP,
			stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
			"const", NULL  );
	}
	/*  volatile  duplicate check  */
	if( CcTypeIsVolatile( qualifier) ){
		volatileCounter = 1;
	}
	volatileCounter += stTypeSpecifierAccess.volatileNum.get( typeSpecifier );
	if( volatileCounter > 1 ){
		CcThrowWarning( CC_DECL_QUALIFIER_OVERLAP,
			stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
			"volatile", NULL  );
	}
	/*  restrict  duplicate check  */
	if( CcTypeIsRestrict( qualifier) ){
		restrictCounter = 1;
	}
	restrictCounter += stTypeSpecifierAccess.restrictNum.get( typeSpecifier );
	if( restrictCounter > 0 ){
		CcThrowWarning( CC_DECL_QUALIFIER_RESTRICT_MISSUSE,
			stTypeSpecifierAccess.codeScp.get( typeSpecifier ),
			"restrict", NULL  );
	}

	newqualifier = CcTypeCreateQualifier( constCounter, volatileCounter, 0 );
	if( qualifier != newqualifier ){
		astElementType = CcTypeAddQualifiedType( astBaseType, newqualifier );
	}else{
		astElementType = astBaseType;
	}
	stTypeSpecifierAccess.typeinfo.set( typeSpecifier, astElementType );
}
static AST ccDeclTypeSpecifier( AST astDeclInfo, UCHAR ucNameSpace )
{
//	S4		nRet ; 			/*戻り値*/
//	S4 	astMemclass ;	/*記憶クラス指定子数*/
//	S4	astKindInfo ;	/*型情報*/
//	S4	astTypeFlag ;	/*型指定子フラグ*/
	AST astTypeSpec=0;
	AST astCurrToken;
	AST astTypeDefToken = 0;
	AST firstScp, secondScp;

//	nRet = COEXIT_SUCCESS;
//	astMemclass = 0 ;
//	astTypeFlag = FALSE ;
//	astKindInfo = 0 ;

	stTypeSpecifierAccess.alloc(1);
	astTypeSpec = stTypeSpecifierAccess.getMax();
	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );
	TRY;
	while(1){
		astCurrToken = CcLexGetCurrToken();
		ccDeclSkipAttribute();
		ccDeclCollectStorageClass( astTypeSpec );
		ccDeclCollectTypeQualifier( astTypeSpec );
		ccDeclCollectBasicType( astTypeSpec );
		ccDeclCollectCompoundType( astTypeSpec );
		ccDeclCollectExtendQualifier( astTypeSpec );
		if( astTypeDefToken != CcLexGetCurrToken() ){
			astTypeDefToken = CcLexGetCurrToken();
			ccDeclTryTypedefSymbol( astTypeSpec, ucNameSpace );
		}
		if( astCurrToken == CcLexGetCurrToken() ){
			/* finished */
			break;
		}
	}
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1));
	secondScp = ccDeclGetCodeScp( firstScp, secondScp );
	stTypeSpecifierAccess.codeScp.set( astTypeSpec, secondScp );
	stTypeSpecifierAccess.declaration.set( astTypeSpec, astDeclInfo );
	ccDeclResolveTypeSpeicifer(astTypeSpec);
	CATCH(astTypeSpec);
	return astTypeSpec;
}
static AST ccDeclNewSymbolInfo( AST astTypeSpec, AST astBaseTypeInfo, AST astToken, UCHAR ucNameSpace ){
	AST astNew=0;
	U2  symClass = 0;

	switch( ucNameSpace ){
	case xNAMESPACE_ARG:{
		symClass = stTypeSpecifierAccess.autoNum.get( astTypeSpec );
		symClass += stTypeSpecifierAccess.externNum.get( astTypeSpec );
		symClass += stTypeSpecifierAccess.staticNum.get( astTypeSpec );
		symClass += stTypeSpecifierAccess.typedefNum.get( astTypeSpec );
		if( symClass > 0 ){
			CcThrowWarning( CC_DECL_FUNC_PARAM_CLASS_ILLEGAL,
				stTypeSpecifierAccess.codeScp.get( astTypeSpec ),
				stLexTokenAccess.name.get( astToken ), NULL  );
		}
		symClass =  stTypeSpecifierAccess.registerNum.get( astTypeSpec );
		if( symClass > 1 ){
			CcThrowWarning( CC_DECL_CLASS_OVERLAP,
				stTypeSpecifierAccess.codeScp.get( astTypeSpec ),
				NULL, NULL  );
		}
		astNew = CcSymNewParameter( stLexTokenAccess.name.get( astToken )  );
		stSymbolInfoAccess.codeScp.set( astNew,stLexTokenAccess.codeScp.get( astToken ));
		if(symClass){
			stSymbolInfoAccess.symClass.set(astNew,CLASS_REGISTER);
		}
		stSymbolInfoAccess.type.set( astNew, astBaseTypeInfo );
		break;
	}
	case xNAMESPACE_MEM:{
		symClass = stTypeSpecifierAccess.autoNum.get( astTypeSpec );
		symClass += stTypeSpecifierAccess.externNum.get( astTypeSpec );
		symClass += stTypeSpecifierAccess.staticNum.get( astTypeSpec );
		symClass += stTypeSpecifierAccess.typedefNum.get( astTypeSpec );
		symClass +=  stTypeSpecifierAccess.registerNum.get( astTypeSpec );
		if( symClass > 0 ){
			CcThrowWarning( CC_DECL_MEMBER_HAS_STORAGECLASS,
				stTypeSpecifierAccess.codeScp.get( astTypeSpec ),
				stLexTokenAccess.name.get( astToken ), NULL  );
		}
		astNew = CcSymNewMember( stLexTokenAccess.name.get( astToken )  );
		stSymbolInfoAccess.codeScp.set( astNew,stLexTokenAccess.codeScp.get( astToken ));
		stSymbolInfoAccess.type.set( astNew, astBaseTypeInfo );
		break;
	}
	case xNAMESPACE_TYPENAME:{
		CcThrowWarning( CC_DECL_TYPENAME_HASSYMBOL,
				stLexTokenAccess.codeScp.get( astToken ),
			stLexTokenAccess.name.get( astToken ), NULL  );
		break;
	}
	case xNAMESPACE_ORD:{
		AST  astManRng = stBlockNestAccess.getMax();
//		BOOL  bAddressed = TRUE;

		symClass = stTypeSpecifierAccess.autoNum.get( astTypeSpec );
		symClass += stTypeSpecifierAccess.externNum.get( astTypeSpec );
		symClass += stTypeSpecifierAccess.staticNum.get( astTypeSpec );
		symClass += stTypeSpecifierAccess.typedefNum.get( astTypeSpec );
		symClass +=  stTypeSpecifierAccess.registerNum.get( astTypeSpec );
		if( symClass > 1 ){
			CcThrowWarning( CC_DECL_CLASS_OVERLAP,
				stTypeSpecifierAccess.codeScp.get( astTypeSpec ),
				NULL, NULL  );
		}
		if( stTypeSpecifierAccess.externNum.get( astTypeSpec ) ){
			symClass = CLASS_EXTERN;
		}else if(stTypeSpecifierAccess.staticNum.get( astTypeSpec ) ){
			symClass = CLASS_STATIC;
		}else if(stTypeSpecifierAccess.registerNum.get( astTypeSpec ) ){
			if( astManRng == MIN_ARRAY ){
				CcThrowWarning( CC_DECL_CLASS_NOT_GBLCLASS,
					stTypeSpecifierAccess.codeScp.get( astTypeSpec ),
					"register", NULL  );
			}
			if( CcTypeIsFunction( astBaseTypeInfo )){
				CcThrowWarning( CC_DECL_FUNC_CLASS_ILLEGAL,
					stTypeSpecifierAccess.codeScp.get( astTypeSpec ),
					"register", NULL  );
			}
			symClass = CLASS_REGISTER;
		}else if(stTypeSpecifierAccess.autoNum.get( astTypeSpec ) ){
			if( astManRng == MIN_ARRAY ){
				CcThrowWarning( CC_DECL_CLASS_NOT_GBLCLASS,
					stTypeSpecifierAccess.codeScp.get( astTypeSpec ),
					"auto", NULL  );
			}
			if( CcTypeIsFunction( astBaseTypeInfo )){
				CcThrowWarning( CC_DECL_FUNC_CLASS_ILLEGAL,
					stTypeSpecifierAccess.codeScp.get( astTypeSpec ),
					"auto", NULL  );
			}
			symClass = CLASS_AUTO;
		}else if(stTypeSpecifierAccess.typedefNum.get( astTypeSpec )){
			symClass = CLASS_TYPEDEF;
//			bAddressed = FALSE;
		}else{
			symClass = 0;
		}
		astNew = CcBlockAddNewSymbol( CcBlockGetCurrInnermostOne(),
				stLexTokenAccess.name.get( astToken ) );
		if( symClass == CLASS_TYPEDEF ){
			CcSymSetToTypedefId( astNew );
		}else if( CcTypeIsFunction(astBaseTypeInfo)){
			CcSymSetToFunction( astNew );
		}else{
			CcSymSetToVariable( astNew );
		}
		stSymbolInfoAccess.codeScp.set( astNew,stLexTokenAccess.codeScp.get( astToken ));
		stSymbolInfoAccess.type.set( astNew, astBaseTypeInfo );
		stSymbolInfoAccess.symClass.set(astNew, symClass );
		break;
	}
	}
	return astNew;
}
static AST ccDeclSetFuncType( AST astBaseTypeInfo, AST astParamDel) {
	AST astParamChain = 0;
	AST astPreOne=0;
	AST astCurrOne=0;
	AST astParamType = 0;
	AST astTempType = 0;
	AST astSym;
	AST astDeclarator;

	if( astParamDel != 0 ){
		if( stDeclarationAccess.next.get( astParamDel ) == 0 ){
			astParamType = CcDeclGetTypeInfo( astParamDel );
			astTempType = CcTypeGetNoQualType( astParamType );
			if( astTempType != 0 && astTempType != TYPE_VOID ){
				astDeclarator = stDeclarationAccess.declarator.get( astParamDel );
				astSym = 0;
				if( astDeclarator != 0 ){
					astSym = CcDeclGetSymfromDec( astDeclarator );
				}
				if( astSym == 0 ){
					astSym = CcSymNewParameter( ""  );
					stSymbolInfoAccess.type.set( astSym, astParamType );
					stSymbolInfoAccess.codeScp.set( astSym, stDeclarationAccess.codeScp.get( astParamDel ));
				}
				stUniteChainAccess.alloc(1);
				astParamChain = stUniteChainAccess.getMax();
				stUniteChainAccess.parameter_sym.set( astParamChain, astSym );
			}else if( astTempType == 0 ){
				/* void */
				stUniteChainAccess.alloc(1);
				astParamChain = stUniteChainAccess.getMax();
				stUniteChainAccess.parameter_sym.set( astParamChain, 0 );
			}
		}else{
			while( astParamDel ){
				astParamType = CcDeclGetTypeInfo( astParamDel );
				astSym = 0;
				if( astParamType != 0 ){
					if( CcTypeIsArray( astParamType ) ){
						astParamType = stTypeInfoAccess.elementType.get( astParamType );
						astParamType = CcTypeAddPointer( astParamType, 0, 0 );
					}else if( CcTypeIsFunction( astParamType )  ){
						astParamType = CcTypeAddPointer( astParamType, 0, 0 );
					}
					astDeclarator = stDeclarationAccess.declarator.get( astParamDel );
					if( astDeclarator != 0 ){
						astSym = CcDeclGetSymfromDec( astDeclarator );
					}
					if( astSym == 0 ){
						astSym = CcSymNewParameter( ""  );
						stSymbolInfoAccess.type.set( astSym, astParamType );
						stSymbolInfoAccess.codeScp.set( astSym, stDeclarationAccess.codeScp.get( astParamDel ));
					}
				}
				/*  astSym = 0 when ... */
				stUniteChainAccess.alloc(1);
				astCurrOne = stUniteChainAccess.getMax();
				stUniteChainAccess.parameter_sym.set( astCurrOne, astSym );
				if( astPreOne ){
					stUniteChainAccess.next.set( astPreOne, astCurrOne );
					stUniteChainAccess.before.set( astCurrOne, astPreOne  );
				}else{
					astParamChain = astCurrOne;
				}
				astPreOne = astCurrOne;
				astParamDel = stDeclarationAccess.next.get( astParamDel ) ;
			}
		}
	}
	astTempType = CcTypeAddFunction(astBaseTypeInfo, astParamChain );
	return astTempType;
}
static S4 ccDeclCreateTypeSymInfo(AST astDeclaration,AST astCurrDeclarator, UCHAR ucNameSpace)
{
	AST astDeclarator=astCurrDeclarator;
	AST astManRng;
	AST astInitExprInfo;
	AST astTypeSpecifierInfo;
	AST astBaseTypeInfo;
	U2  usDeclKind;
	U2  u2_Funcflg = 0;
	AST astSymInfo=0;

	TRY;
	astManRng = stBlockNestAccess.getMax();
	astInitExprInfo = 0 ;
	astTypeSpecifierInfo = stDeclarationAccess.typeSpecifier.get(astDeclaration) ;
	astBaseTypeInfo = stTypeSpecifierAccess.typeinfo.get( astTypeSpecifierInfo );

    while( astDeclarator != 0 ){
    	usDeclKind = stDeclaratorAccess.declaratorKind.get( astDeclarator );
        if( usDeclKind == xDECLARATOR_POINTER ){
        	U2 nTypeModifier;
        	U2 usConstNum;
        	U2 usVolatileNum;
        	U2 usRestrictNum;
        	U4 ulSize;

        	nTypeModifier = 0 ;
        	usConstNum = stDeclaratorAccess.constNum.get( astDeclarator );
        	if( usConstNum >= 2 ){
        		CcThrowWarning( CC_DECL_QUALIFIER_OVERLAP,
        				stDeclaratorAccess.codeScp.get( astDeclarator ),
        			"const", NULL  );
        	}
        	usVolatileNum = stDeclaratorAccess.volatileNum.get( astDeclarator );
        	if( usVolatileNum >= 2 ){
        		CcThrowWarning( CC_DECL_QUALIFIER_OVERLAP,
        				stDeclaratorAccess.codeScp.get( astDeclarator ),
        			"volatile", NULL  );
        	}
        	usRestrictNum = stDeclaratorAccess.restrictNum.get( astDeclarator );
        	if( usRestrictNum >= 2 ){
        		CcThrowWarning( CC_DECL_QUALIFIER_OVERLAP,
        				stDeclaratorAccess.codeScp.get( astDeclarator ),
        			"restrict", NULL  );
        	}
        	nTypeModifier = CcTypeCreateQualifier( usConstNum, usVolatileNum, usRestrictNum );

        	if( stCoreEnvInfo.ucNearFar ){
        		if( u2_Funcflg ){
        			if( stTypeSpecifierAccess.nearNum.get( astTypeSpecifierInfo ) ){
                		CcThrowWarning( CC_DECL_FUNC_CLASS_NEARPOINTER,
                			stTypeSpecifierAccess.codeScp.get( astTypeSpecifierInfo ),
                			NULL, NULL  );
        			}
        			ulSize = FARPOINTERSIZE ;
        		}else if( stTypeSpecifierAccess.farNum.get( astTypeSpecifierInfo ) ){
        			/* 関数又はfar有りの場合 */
        			ulSize = FARPOINTERSIZE ;
        		}else{
        			/* 変数、nearありまたはなしの場合*/
        			ulSize = NEARPOINTERSIZE;
        		}
        	}else{
        		ulSize = POINTERSIZE;
        	}
        	astBaseTypeInfo = CcTypeAddPointer( astBaseTypeInfo, ulSize, nTypeModifier );
        	stDeclaratorAccess.type.set( astDeclarator, astBaseTypeInfo );
        	astDeclarator = stDeclaratorAccess.childDeclarator.get(astDeclarator);
        }else if( usDeclKind == xDECLARATOR_ARRAY ){
        	AST astConstExprInfo;
        	AST astConstInfo;
        	U4 ulSize;
        	AST astType;
        	BOOL bVariable = FALSE;

			if (CcTypeIsFunction(astBaseTypeInfo) ){
        		CcThrowWarning( CC_DECL_ARRAY_ORITYPE_FUNC,
        			stDeclaratorAccess.codeScp.get( astDeclarator ),
        			NULL, NULL  );
			}
			astConstExprInfo = stDeclaratorAccess.arrayIdx.get( astDeclarator) ;
        	if( astConstExprInfo >= MIN_ARRAY ){
        		astConstInfo = stExpressionAccess.constValue.get( astConstExprInfo );
        		if( astConstInfo > 0 ){
            		astType = stValueInfoAccess.type.get( astConstInfo );
    	        	if( CcTypeIsInteger( astType ) ){
    					VARVALUE v = CcValueGetInteger( astConstInfo );
    					if( v.sign > 0 ){
    						ulSize = v.u8Remainder;
    					}else{
    						sprintf( gblTempBuffer, "-%I64u", v.u8Remainder );
    						CcThrowWarning( CC_DECL_ARRAY_INDEX_NEGATIVE,
    								stExpressionAccess.codeScp.get( astConstExprInfo ),
    								gblTempBuffer, NULL );
    						ulSize = 1;
    					}
    	        	}else{
    					CcThrowWarning( CC_DECL_ARRAY_INDEX_NOTINTEGER,
    							stDeclaratorAccess.codeScp.get( astDeclarator ),
    							gblTempBuffer, NULL  );
						DOUBLE db = CcValueGetFloating( astConstInfo );
						ulSize = (U4)db;
    	        	}
        		}else{
        			if( stCoreEnvInfo.ucC99 == TRUE || stCoreEnvInfo.ucGNU  == TRUE  ){
        				ulSize = 0;
        				bVariable = TRUE;
        			}else{
        				ulSize = 1;
        			}
        		}

        	}else{
        		ulSize = 0;
        	}

        	astBaseTypeInfo = CcTypeAddArray( astBaseTypeInfo, ulSize );

        	if( astConstExprInfo < MIN_ARRAY ){
        		stTypeInfoAccess.bSizeUnDefined.set( astBaseTypeInfo, TRUE );
        	}else{
        		stTypeInfoAccess.bVariableSize.set( astBaseTypeInfo, bVariable );
        	}
        	stDeclaratorAccess.type.set( astDeclarator, astBaseTypeInfo );
        	astDeclarator = stDeclaratorAccess.childDeclarator.get(astDeclarator);
        }else if( usDeclKind == xDECLARATOR_FUNC ){
        	AST astParamentChain;

        	u2_Funcflg = TRUE;
			if (CcTypeIsFunction(astBaseTypeInfo) || CcTypeIsArray(astBaseTypeInfo) ){
        		CcThrowWarning( CC_DECL_FUNC_RETURNTYPE_ILLEGAL,
        			stDeclaratorAccess.codeScp.get( astDeclarator ),
        			NULL, NULL  );
			}
			astParamentChain = stDeclaratorAccess.paramChain.get( astDeclarator );
			astBaseTypeInfo = ccDeclSetFuncType(astBaseTypeInfo, astParamentChain) ;
			stDeclaratorAccess.type.set( astDeclarator, astBaseTypeInfo );
			astDeclarator = stDeclaratorAccess.childDeclarator.get(astDeclarator);
        }else if( usDeclKind == xDECLARATOR_SYM ){
        	AST astToken;

        	stDeclaratorAccess.type.set( astDeclarator, astBaseTypeInfo );
        	astToken = stDeclaratorAccess.symbol.get( astDeclarator );

        	astSymInfo = ccDeclNewSymbolInfo( astTypeSpecifierInfo, astBaseTypeInfo, astToken, ucNameSpace );

            if( CcTypeIsBitfield(astBaseTypeInfo) ){
				if( 0 == stTypeInfoAccess.size.get( astBaseTypeInfo )){
					CcThrowWarning( CC_DECL_MEMBER_BIT_0BIT_SYM,
						stDeclaratorAccess.codeScp.get( astDeclarator ),
						stLexTokenAccess.name.get( astToken ), NULL  );
                }
            }
    		if( astInitExprInfo ){
    			if( stSymbolInfoAccess.symClass.get( astSymInfo ) == CLASS_TYPEDEF ){
        			CcThrowWarning( CC_DECL_TYPEDEF_SYM_INITIALLED,
        					stExpressionAccess.codeScp.get( astSymInfo ),
        					stSymbolInfoAccess.name.get( astSymInfo ), NULL );

    			}else{
    				stSymbolInfoAccess.initialExpList.set( astSymInfo, astInitExprInfo );
    			}
    		}

    		stDeclaratorAccess.symbol.set( astDeclarator, astSymInfo );
    		astDeclarator = stDeclaratorAccess.childDeclarator.get(astDeclarator);
        }else if( usDeclKind == DECLARATOR_BITFIELD ){
        	U4	ulSize=0 ;			/*サイズ			*/
        	U4  ulTempSize;
        	AST astConstExprInfo;
        	AST astConstInfo = 0;
        	AST astType;
        	U2  u2_SignFlg = 0;
        	U2 nTypeModifier;

        	if( stCoreEnvInfo.ucBitType == TRUE ){
    			if (!CcTypeIsInteger(astBaseTypeInfo)){
        			CcThrowWarning( CC_DECL_MEMBER_BIT_TYPE_ILLEGAL,
        					stDeclaratorAccess.codeScp.get( astDeclarator ),
        					NULL, NULL );
    			}
        	}else{
        		if( !CcTypeIsInt(astBaseTypeInfo) ){
        			CcThrowWarning( CC_DECL_MEMBER_BIT_TYPE_ILLEGAL,
        					stDeclaratorAccess.codeScp.get( astDeclarator ),
        					NULL, NULL );
        		}
        	}
        	astConstExprInfo = stDeclaratorAccess.bitIdx.get( astDeclarator );
        	if( astConstExprInfo > 0 ){
        		astConstInfo = stExpressionAccess.constValue.get( astConstExprInfo );
        		astType = stValueInfoAccess.type.get( astConstInfo );
	        	if( CcTypeIsInteger( astType ) ){
	        		VARVALUE v = CcValueGetInteger( astConstInfo );
	        		if( v.sign > 0 ){
	        			ulSize = v.u8Remainder;
	        		}else{
	        			sprintf( gblTempBuffer, "-%I64u", v.u8Remainder );
	           			CcThrowWarning( CC_DECL_MEMBER_BIT_WIDTH_ILLEGAL,
	            					stDeclaratorAccess.codeScp.get( astDeclarator ),
	            					gblTempBuffer, NULL );
	        			ulSize = 1;
	        		}
	        	}else{
	        		DOUBLE db = CcValueGetFloating( astConstInfo );
	        		sprintf( gblTempBuffer, "%f", db );
           			CcThrowWarning( CC_DECL_MEMBER_BIT_WIDTH_ILLEGAL,
            					stDeclaratorAccess.codeScp.get( astDeclarator ),
            					gblTempBuffer, NULL );
	        		ulSize = 1;
	        	}
        	}else{
       			CcThrowWarning( CC_DECL_MEMBER_BIT_WIDTH_NONE,
        					stDeclaratorAccess.codeScp.get( astDeclarator ),
        					"", NULL);
        		ulSize = 1;
        	}
        	ulTempSize = stTypeInfoAccess.size.get(astBaseTypeInfo);
			if ( (U4)ulTempSize * CHARBIT < (U4)ulSize) {
				sprintf( gblTempBuffer, "%lu", ulSize );
				gblTempBuffer[49]=0;
				sprintf( &gblTempBuffer[50], "%lu", (U4)ulTempSize * CHARBIT );
       			CcThrowWarning( CC_DECL_MEMBER_BIT_WIDTH_OVERFLOW,
        					stDeclaratorAccess.codeScp.get( astDeclarator ),
        					gblTempBuffer, NULL );
			}
        	if( CcTypeIsSpecifiedSigned( astBaseTypeInfo ) ){
        		u2_SignFlg = stTypeInfoAccess.signFlag.get( astBaseTypeInfo );
        	}else if( CcTypeIsSpecifiedUnSigned( astBaseTypeInfo ) ){
        		u2_SignFlg = stTypeInfoAccess.signFlag.get( astBaseTypeInfo );
        	}else{
        		if( stCoreEnvInfo.ucBitSign == OPT_BIT_UNSIGNED ){
        			u2_SignFlg = SIGN_UNSIGNED;
        		}
        		else if ( stCoreEnvInfo.ucBitSign == OPT_BIT_SIGNED ){
        			u2_SignFlg = SIGN_SIGNED;
        		}
        		else{
        			u2_SignFlg = stTypeInfoAccess.signFlag.get( astBaseTypeInfo );
        		}
        	}
        	nTypeModifier = stTypeInfoAccess.typeQual.get( astBaseTypeInfo) ;
        	astBaseTypeInfo = CcTypeAddBitfield( astBaseTypeInfo, ulSize, u2_SignFlg, nTypeModifier  );
        	stDeclaratorAccess.type.set(astDeclarator, astBaseTypeInfo);
        	astDeclarator = stDeclaratorAccess.childDeclarator.get(astDeclarator);
        }
        else if( usDeclKind == xDECLARATOR_INIT ){
        	astInitExprInfo = stDeclaratorAccess.initialExpList.get( astDeclarator );
        	astDeclarator = stDeclaratorAccess.childDeclarator.get(astDeclarator);
        }
        else{
        	astDeclarator = stDeclaratorAccess.childDeclarator.get(astDeclarator);
        }
    }

    if( astInitExprInfo >= MIN_ARRAY ){
    	if( astManRng == MIN_ARRAY || stTypeSpecifierAccess.staticNum.get( astTypeSpecifierInfo ) ){
    		ccDeclCheckInitAndType(astBaseTypeInfo, astInitExprInfo, TRUE ) ;
    	}else{
    		ccDeclCheckInitAndType(astBaseTypeInfo, astInitExprInfo, FALSE ) ;
    	}
    }
	if( astSymInfo != 0
		&& 0 == stTypeSpecifierAccess.typedefNum.get( astTypeSpecifierInfo )
		&& ( 0 == stTypeInfoAccess.size.get( astBaseTypeInfo) )
		&& ( FALSE == stTypeInfoAccess.bVariableSize.get( astBaseTypeInfo ))){
		if( astManRng > MIN_ARRAY && !CcTypeIsFunction(astBaseTypeInfo) ){
			if( ucNameSpace != xNAMESPACE_MEM
				&&( 0 == stTypeSpecifierAccess.externNum.get(astTypeSpecifierInfo))){
       			CcThrowWarning( CC_DECL_VARI_TYPE_INCOMPLETE,
        					stDeclaratorAccess.codeScp.get( astCurrDeclarator ),
        					stSymbolInfoAccess.name.get( astSymInfo ), NULL );
			}
		}else if ( CcTypeIsBasicType(astBaseTypeInfo)){
   			CcThrowWarning( CC_DECL_VARI_TYPE_INCOMPLETE,
    					stDeclaratorAccess.codeScp.get( astCurrDeclarator ),
    					stSymbolInfoAccess.name.get( astSymInfo ), NULL );
		}
	}
	CATCH(astSymInfo);
    return( astSymInfo ) ;
}

static  VOID  ccDeclSuffix_OpenBlock( AST astDeclarator, AST astSymbol, UCHAR ucNameSpace ){
	AST astFuncBody=0;
	AST astDCnt;
	AST astTypeInfo;
	U2  declaratorKind;


	if( ucNameSpace == xNAMESPACE_MEM ){
		/*  { を含んではいけないので、ERROR  */
		CcThrowWarning( CC_DECL_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( CcLexGetCurrToken() ),
					stLexTokenAccess.name.get( CcLexGetCurrToken() ), NULL );
		return;
	}
	TRY;
	astFuncBody = CcStmtFuncBody( KIND_SYMDEFINFO, astSymbol);
	/* keep going as if it was function-definition */
	/* Check the function  format  */
	CATCH( (VOID)0 );
	astDCnt = stDeclaratorAccess.declaration.get( astDeclarator );
	if( stDeclarationAccess.declarator.get( astDCnt ) != astDeclarator ){
		/*  int a, main( void ){} ? */
		/*  donot know whether it's a function-prototype which misses its semicolon
		 *   or it's a function-definition which gets wrong formation
		 */
		CcThrowWarning( CC_DECL_FUNC_SYNTAX_ILLEGAL,
			stLexTokenAccess.codeScp.get( CcLexGetCurrToken() ),
			stLexTokenAccess.name.get( CcLexGetCurrToken() ), NULL );
	}
	/* is it a function -type ?*/
	astTypeInfo = stSymbolInfoAccess.type.get( astSymbol );
	if( !CcTypeIsFunction( astTypeInfo )){
		CcThrowWarning( CC_DECL_SYNTAX_ERROR,
			stLexTokenAccess.codeScp.get( CcLexGetCurrToken() ),
			stLexTokenAccess.name.get( CcLexGetCurrToken() ), NULL );
	}
	/* Is there function-declarator?
	 * function-definition can not be defined by typedef symbol  */
	astDCnt = astDeclarator;
	while( astDCnt != 0 ){
		declaratorKind = stDeclaratorAccess.declaratorKind.get( astDCnt );
		if( declaratorKind == xDECLARATOR_FUNC ){
			break ;
		}
		astDCnt = stDeclaratorAccess.childDeclarator.get( astDCnt );
	}
	if( astDCnt == 0 ){
		/*  it is defined by typedef symbol  */
		CcThrowWarning( CC_DECL_FUNC_SYNTAX_ILLEGAL,
			stLexTokenAccess.codeScp.get( CcLexGetCurrToken() ),
			stLexTokenAccess.name.get( CcLexGetCurrToken() ), NULL );
	}
	if( astSymbol == 0 ){
		/*  miss the function name  */
		CcThrowWarning( CC_DECL_FUNC_SYNTAX_ILLEGAL,
			stLexTokenAccess.codeScp.get( CcLexGetCurrToken() ),
			stLexTokenAccess.name.get( CcLexGetCurrToken() ), NULL );
	}

//	RetUshort = stSymbolInfoAccess.symClass.get( astSymbol );
//	if ( RetUshort == 0 ){
//		stSymbolInfoAccess.symClass.set( astSymbol, CLASS_EXTERN );
//    }
	stSymbolInfoAccess.functionBody.set( astSymbol, astFuncBody );
}
static VOID ccDeclAddToSection( AST astSym ){
	//TODO: ;
}
VOID CcDeclInit(VOID){

}
BOOL CcDeclIsDeclaration( VOID ){
	AST   astCurrToken ;
	AST   astCurrBlock;

	astCurrBlock = stBlockNestAccess.getMax();
	if( astCurrBlock <= MIN_ARRAY ){
		return TRUE;
	}
	astCurrToken = CcLexGetCurrToken();
	return CcDeclChkType(astCurrToken);
}

/*************************************************************
 * analyze a declaration.
 *   variable, member, argument or type-name  which is identified by
 *   the parameter 'ucNameSpace'.
 * return the index of new declaration when succeeded.
 * otherwise return 0.
 **************************************************************/
AST CcDeclaration( UCHAR ucNameSpace )
{
	AST	astDeclInfo=0;					/* 宣言情報			*/
	AST	astDeclaratorInfo;				/* 宣言子情報			*/
	AST astSpecType;
	AST	astAnalyticalDeclaratorInfo;	/* 解析宣言子情報		*/
	AST	astSymInfo;						/* シンボル情報		*/
	BOOL	RetBool;	/* 戻り値 */
	U4  currTokenKind ;
	AST   firstCodeScp, secondCodeScp;
	AST   astCurrToken ;


	astCurrToken = CcLexGetCurrToken();
	/*  blank ?  */
	RetBool = ccDeclTestDelimiter( ucNameSpace );
	if( RetBool ){
		return 0;
	}
	TRY;
	firstCodeScp = stLexTokenAccess.codeScp.get( astCurrToken );
	/*  new declaration */
	stDeclarationAccess.alloc(1);

	astDeclInfo = stDeclarationAccess.getMax();
	/* type specifier begins */
	astSpecType = ccDeclTypeSpecifier( astDeclInfo, ucNameSpace);
	stDeclarationAccess.typeSpecifier.set(astDeclInfo, astSpecType);
	stDeclarationAccess.namespace.set( astDeclInfo, ucNameSpace );
	/* type specifier finished */
	/*  blank ?  */
	RetBool = ccDeclTestDelimiter( ucNameSpace );
	if( RetBool ){

		secondCodeScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
		stDeclarationAccess.codeScp.set( astDeclInfo, ccDeclGetCodeScp(firstCodeScp,secondCodeScp) );
		ccDeclCreateTypeSymInfo(astDeclInfo, 0, ucNameSpace);
		if( ucNameSpace == xNAMESPACE_ORD ){
			ccDeclAlertBlankDeclaration( astDeclInfo );
		}
		return astDeclInfo;
	}
	astDeclaratorInfo = 0;

	while(1)
	{
		astAnalyticalDeclaratorInfo = ccDeclDeclarator(astDeclInfo, ucNameSpace );
		/* S Maintenance data structure of declarator */
		if(astDeclaratorInfo == 0){
			stDeclarationAccess.declarator.set( astDeclInfo, astAnalyticalDeclaratorInfo );
		}else{
			stDeclaratorAccess.nextDeclarator.set(astDeclaratorInfo, astAnalyticalDeclaratorInfo);
		}
		/* E Maintenance data structure of declarator */

		/* get the variable */
		astDeclaratorInfo = astAnalyticalDeclaratorInfo;
		if ( astDeclaratorInfo != 0 ){
			stDeclaratorAccess.declaration.set( astDeclaratorInfo, astDeclInfo );
			astSymInfo = ccDeclCreateTypeSymInfo(astDeclInfo, astDeclaratorInfo, ucNameSpace);
			ccDeclAddToSection( astSymInfo );
		}else{
			/* no variable */
			astSymInfo = 0;
		}
		if( xNAMESPACE_TYPENAME == ucNameSpace ){
			/* cast or size-of or Compound literals  */
			break;
		}else if( ucNameSpace == xNAMESPACE_ARG ){
			/*  the argument declaration should be finished. */
			break;
		}
		astCurrToken = CcLexGetCurrToken();
		/*  ucNameSpace  xNAMESPACE_MEM  or  xNAMESPACE_ORD  */
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		switch(currTokenKind){
			case xLEX_OPENBLOCK:
				ccDeclSuffix_OpenBlock( astAnalyticalDeclaratorInfo, astSymInfo,
						ucNameSpace);

				if( ucNameSpace == xNAMESPACE_ORD ){
					CcLinkageSet(astSymInfo, astAnalyticalDeclaratorInfo );
				}
				break;
			case xLEX_SEMICOLON:
				if( ucNameSpace == xNAMESPACE_ORD ){
					CcLinkageSet(astSymInfo, astAnalyticalDeclaratorInfo );
				}
				CcLexGetNextToken();
				break;
			case xLEX_COMMA:
				if ( astSymInfo >= MIN_ARRAY ){
					/*  int main( void ){}, a; ? */
					if( stSymbolInfoAccess.functionBody.get( astSymInfo ) ){
						CcThrowWarning( CC_DECL_FUNC_SYNTAX_ILLEGAL,
							stLexTokenAccess.codeScp.get( CcLexGetCurrToken() ),
							stLexTokenAccess.name.get( CcLexGetCurrToken() ), NULL );
					}
				}
				CcLexGetNextToken();
				if( ucNameSpace == xNAMESPACE_ORD ){
					CcLinkageSet(astSymInfo, astAnalyticalDeclaratorInfo );
				}

				continue;
			case xLEX_CLOSEPAREN:
				CcThrowWarning( CC_DECL_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						")", NULL );
				CcLexGetNextToken();
				if( ucNameSpace == xNAMESPACE_ORD ){
					CcLinkageSet(astSymInfo, astAnalyticalDeclaratorInfo );
				}
				break;
			case xLEX_CLOSEBLOCK:
				if( ucNameSpace == xNAMESPACE_MEM ){
					/*  struct st{ int a; int b }; */
					CcThrowWarning( CC_DECL_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( CcLexGetCurrToken() ),
						stLexTokenAccess.name.get( CcLexGetCurrToken() ), NULL );
				}
				CcLexGetNextToken();
				if( ucNameSpace == xNAMESPACE_ORD ){
					CcLinkageSet(astSymInfo, astAnalyticalDeclaratorInfo );
				}
				break;
			default:
				CcThrowWarning( CC_DECL_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
				if( ucNameSpace == xNAMESPACE_ORD ){
					CcLinkageSet(astSymInfo, astAnalyticalDeclaratorInfo );
				}
				break ;
		}
		break ;
	}
	secondCodeScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	stDeclarationAccess.codeScp.set( astDeclInfo, ccDeclGetCodeScp(firstCodeScp,secondCodeScp) );
	CATCH(0);
	return astDeclInfo;
}
/*************************************************************
 * Check whether the token which is inputed replaces a type.
 * return true when it's a keyword or typedef symbol.
 * otherwise return false.
 **************************************************************/
BOOL CcDeclChkType(AST astToken){
	AST astSymbolInfo;
	if( CcLexIsDeclarationKeyword( astToken ) ){
		return TRUE;
	}
	if( stLexTokenAccess.tokenKind.get(astToken) == xLEX_SYMBOL ){
		astSymbolInfo = CcBlockFindSymbol( stLexTokenAccess.name.get(astToken), NULL ) ;
		if( astSymbolInfo == 0 ){
			return( FALSE );
		}
		if( CcSymIsTypedef(astSymbolInfo) ){
			return( TRUE ) ;
		}
	}
	return FALSE;
}
AST  CcDeclGetSymfromDec( AST astDeclarator ){
	AST	astTemp;	/*テンポラリ変数*/
	U2	RetUshort;

	if( astDeclarator == 0 ){
		return(0L);
	}
	astTemp = stDeclaratorAccess.childDeclarator.get( astDeclarator );
	while (astTemp != 0){
		astDeclarator = astTemp;
		astTemp = stDeclaratorAccess.childDeclarator.get( astDeclarator );
	}
	RetUshort = stDeclaratorAccess.declaratorKind.get( astDeclarator );
	if (RetUshort != xDECLARATOR_SYM){
		return (0L);
	}
	astTemp = stDeclaratorAccess.symbol.get( astDeclarator );
	return( astTemp ) ;
}
/*************************************************************
 * Analyze declaration list.
 * 	the global declarations.
 * return the first declaration of the declaration's chain when succeeded.
 * return 0 while failed or empty translation-Unit.
 **************************************************************/
AST  CcDeclarationList( VOID ){
	AST astCurrToken, astPreToken=0;
	U4  currTokenKind;
	AST astTempDec, astPreDec=0;
	AST astResult=0;

	TRY;
	astCurrToken = CcLexGetNextToken() ;
	astPreToken = astCurrToken;
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	while( astCurrToken >= MIN_ARRAY ){
		 if(currTokenKind == xLEX_ENDOFFILE){
			 break ;
		 }
		 if(currTokenKind == xLEX_SEMICOLON){
			 astCurrToken = CcLexGetNextToken() ;
			 currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			 astPreToken = astCurrToken;
			 continue;
		 }
		 astTempDec = CcDeclaration( xNAMESPACE_ORD) ;
		 if( astTempDec >= MIN_ARRAY ){
			 if( astPreDec == 0 ){
				 astResult = astTempDec;
			 }else{
				 stDeclarationAccess.next.set( astPreDec, astTempDec );
			 }
			 astPreDec = astTempDec;
		 }
		 astCurrToken = CcLexGetCurrToken() ;
		 if( astPreToken == astCurrToken ){
			 astCurrToken = CcLexGetNextToken() ;
		 }
		 currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		 astPreToken = astCurrToken;
	}
	CATCH( astResult );
	return astResult;
}
AST  CcDeclGetTypeInfo( AST  astDeclaration ){
	AST astTypeSpec = stDeclarationAccess.typeSpecifier.get( astDeclaration );
	AST astDeclarator = stDeclarationAccess.declarator.get( astDeclaration );
	AST astType = stTypeSpecifierAccess.typeinfo.get( astTypeSpec );
	while( astDeclarator ){
		astType = stDeclaratorAccess.type.get( astDeclarator );
		astDeclarator = stDeclaratorAccess.childDeclarator.get( astDeclarator );
	}
	return astType;
}
/* end of file */
